7
votes

Déterminer si un élément est une chaîne ou une liste dans Erlang

J'écris un programme pouvant avoir une liste ou une chaîne comme argument. Comment puis-je dire la différence entre une chaîne et une liste par programme à Erlang. Quelque chose comme: xxx


0 commentaires

4 Réponses :


7
votes

io_lib: imprimable_list pourrait être ce que vous recherchez. Cependant, il ne gère pas Unicode uniquement les codages latin-1. Si vous avez besoin de détecter les chaînes UNICODE, je pense que vous pourriez avoir du mal de la chance. Le meilleur pari est pseudo tapitant vos listes comme: {string, [$ a, $ b, $ c]} . Sorte de créer vos types.

Utilisez un constructeur comme string (L) lorsque IS_List (L) -> {String, L} . et utilisez simplement que la saisie de la construction de votre application.

D'autre part, vous pouvez simplement traiter toutes les cordes comme des listes et ne pas faire la distinction.


2 commentaires

Merci. Oui, j'ai pensé à ce pseudo typing, mais je ne savais pas si c'était un bon moyen de faire des choses à Erlang.


Une autre option que j'ai vue utilisée est de garder toutes les cordes comme des binaires.



4
votes

meilleure chose que vous pouvez faire est de marquer vos structures comme Mur Jeremy Gèred . Quoi qu'il en soit, vous pouvez choisir l'entrée de cocher à votre module / sous-système / application / ... xxx

Malheureusement, il est opération coûteux et vous ne pouvez pas l'utiliser dans des gardes.


2 commentaires

Mais alors une liste apparaîtrait comme une chaîne dans votre exemple, est-ce correct?


Je ne comprends pas la question. Voulez-vous dire quelque chose comme new_string (x) -> true = is_string (x), {chaîne, x}. ? Alors la réponse est oui.



1
votes

Pourquoi auriez-vous besoin de les séparer? Les chaînes sont des listes d'erlang (la plupart du temps).


2 commentaires

La raison la plus courante dont vous auriez besoin pour faire est une liste imbriquée dans un arbre où certaines des sous-listes sont des chaînes qui doivent être traitées comme une entrée de liste et non un sous-arbre. Sans marquer les opérations de liste comme l'aplatissement et la traversée d'arbres deviennent beaucoup plus difficiles.


DROITE, dans ce cas, je seconde votre solution avec pseudo-tapant comme un moyen de construire votre propre chemin de contrôle.



4
votes

Erlang implémente différentes fonctions à tester si une liste est une liste plate dans le module IO_LIB. Malgré le commentaire de Seremy Wall, il existe une fonction de tester si une liste à plat contient des caractères Unicode ainsi que la version Latin1.

Si vous souhaitez tester pour les listes plats Unicode, vous pouvez utiliser io_lib: Char_list (terme) http://erlang.org/doc/man/io_lib.html#char_list- 1 p>

io_lib: char_list / 1 La mise en œuvre de la fonction est la suivante: p>

latin1_char_list([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
      latin1_char_list(Cs);
latin1_char_list([]) -> true;
latin1_char_list(_) -> false.


1 commentaires

Même votre réponse est parfaitement correcte, vous n'avez pas à bowner ma réponse. C'était parfaitement correct dans le temps quand j'ai répondu. Recherchez la date et lorsque le support Unicode a été ajouté à io_lib inerlang / OTP Distribution.