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

2019-06-21 06:19发布

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.

标签: erlang
4条回答
Melony?
2楼-- · 2019-06-21 06:45

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

查看更多
女痞
3楼-- · 2019-06-21 06:51

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.

查看更多
我只想做你的唯一
4楼-- · 2019-06-21 06:51

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.

查看更多
戒情不戒烟
5楼-- · 2019-06-21 06:58

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.

查看更多
登录 后发表回答