2010-03-19 3 views
5

Я пишу программу, которая может иметь либо список, либо строку в качестве аргумента. Как я могу определить разницу между строкой и списком программно в Erlang. Что-то вроде:Определение того, является ли элемент строкой или списком в Erlang

print(List) -> list; 
print(String) -> string. 

ответ

6

io_lib: printable_list может быть тем, что вы ищете. Однако он не обрабатывает кодировки только в кодировке latin-1 в формате unicode. Если вам нужно определить строки юникода, я думаю, вам может быть не повезло. Лучше всего называть ваши списки так: {строка, [$ a, $ b, $ c]}. Вид сборки ваших типов.

использовать конструктор типа string (L), когда is_list (L) -> {string, L}.

и просто используйте эту типизирующую конструкцию через ваше приложение.

С другой стороны, вы можете просто рассматривать все строки как просто списки и не делать различия.

+0

Спасибо. да, я действительно думал об этом псевдопечатании, но я не знал, хорошо ли это сделать в Эрланге. – Zubair

+0

Другим вариантом, который я видел, является сохранение всех строк в виде двоичных файлов. –

3

Лучшее, что вы можете сделать, это пометить ваши структуры как Jeremy Wallsuggested. В любом случае вы можете решить контрольный вход для вашего модуля/подсистемы/приложения/...

is_string([]) -> true; 
is_string([X|T]) -> is_integer(X) andalso X>=0 andalso is_string(T); 
is_string(_) -> false. 

К сожалению, это дорогостоящая операция, и вы не можете использовать его в охранниках.

+0

Но тогда список будет отображаться как строка в вашем примере, это правильно? – Zubair

+0

Не понимаю вопрос. Вы имеете в виду что-то вроде 'new_string (X) -> true = is_string (X), {string, X} .'? Так что да. –

0

Зачем вам их разделять? Строки - это списки в erlang (большую часть времени).

+1

Наиболее распространенная причина, по которой вам нужно будет сделать это, - это вложенные списки в дереве, где некоторые из подписок являются строками, которые нужно рассматривать как запись списка, а не поддерево. Без пометки операции списка, такие как сглаживание и обход дерева, становятся намного сложнее. –

+0

Правильно, в этом случае я заставлю ваше решение с помощью псевдопечатания, поскольку это способ создания собственного способа управления потоком. – Weasel

3

Erlang реализует различные функции, чтобы проверить, является ли список плоским списком в модуле io_lib. Несмотря на комментарий Джереми Стена, есть функция проверки, если плоский список содержит символы Юникода, а также версию latin1.

Если вы хотите проверить для плоских списков Юникода вы можете использовать io_lib: char_list (Term) http://erlang.org/doc/man/io_lib.html#char_list-1

io_lib: 1 реализация char_list/функция:

char_list([C|Cs]) when is_integer(C), C >= 0, C < 16#D800; 
     is_integer(C), C > 16#DFFF, C < 16#FFFE; 
     is_integer(C), C > 16#FFFF, C =< 16#10FFFF -> 
    char_list(Cs); 
char_list([]) -> true; 
char_list(_) -> false. 

Один хороший выбор для проверки latin1, закодированные строки является io_lib: latin1_char_list (срок) http://erlang.org/doc/man/io_lib.html#latin1_char_list-1

io_lib: latin1_char_list/1 реализация функции :

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. 

Проверьте документацию модуля io_lib на другие подобные функции.

+0

Даже ваш ответ совершенно правильный, вам не нужно понижать мой ответ. Это было совершенно правильно, когда я ответил на это.Посмотрите дату и когда поддержка Unicode была добавлена ​​в дистрибутив io_lib'Erlang/OTP. –

Смежные вопросы