Determining if an item is a string or a list in Er

2019-06-21 06:37发布

问题:

I am writing a program that can have either a list or a string as an argument. How can I tell the difference between a string and a list programmatically in Erlang. Something like:

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

回答1:

io_lib:printable_list might be what you are looking for. However it doesn't handle unicode only latin-1 encodings. If you need to detect unicode strings I think you might be out of luck. The best bet is pseudo typing your lists like so: {string, [$a, $b, $c]}. Kind of a build your types.

use a constructor like so string(L) when is_list(L) -> {string, L}.

and just use that typing construct all through your app.

On the other hand you could just treat all strings as just lists and not make the distinction.



回答2:

Best thing what you can do is tagging your structures as Jeremy Wall suggested. Anyway you can decide check input to your module/subsystem/application/...

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

Unfortunately it is expensive operation and you can't use it in guards.



回答3:

Erlang implements different functions to test if a list is a flat list in module io_lib. Despite Jeremy Wall comment there is a function to test if a flat list contains unicode characters as well as latin1 version.

If you want to test for flat unicode lists you can use io_lib:char_list(Term) http://erlang.org/doc/man/io_lib.html#char_list-1

io_lib:char_list/1 function implementation is:

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.

One good choice for checking latin1 encoded strings is io_lib:latin1_char_list(Term) http://erlang.org/doc/man/io_lib.html#latin1_char_list-1

io_lib:latin1_char_list/1 function implementation is:

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.

Check the io_lib module documentation for other similar functions.



回答4:

Why would you need to separate these? Strings are lists in erlang (most of the time).



标签: erlang