Erlang Mailing Lists

Author Message

<  Erlang  ~  Problem processing a list

brett hallett
Posted: Mon Sep 03, 2007 12:16 pm Reply with quote
User Joined: 21 Aug 2007 Posts: 21
I'm trying to 'pop' entries off a list and print each one seperately,
but my attempts at printing abort when I try to output a single entry
in my print function.

Also how does one test for 'end-of-list' ??

Thanks,
Brett

================= test module ============
-module(numbers).

%% extract numerics from a mixed text line
%% eg "12cd 45erw 4rfr 22ss" => [12,45,4,22]
-export([ start/0 ]).

print( [L]) ->
[L1 | L ] = L,
io:format('~p~n', [L1]),
print(L);

print(0) -> ok.

start() ->
Txt ="098m 03 r9 f80239802389f0m9KDKLKLJDKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl djkl djkl d00000002998",
io:format("~s ~n", [Txt]),
Txt2 = string:tokens(Txt," abcdefghijklmnopqysruvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
io:format("~p~n", [Txt2]),
print(Txt2).

==================== execution ==============
111> c(numbers.erl).
{ok,numbers}
112> numbers:start().
098m 03 r9 f80239802389f0m9KDKLKLJDKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl djkl djkl d00000002998
["098",
"03",
"9",
"80239802389",
"0",
"9",
"0983",
"890",
"03",
"3",
"4",
"3",
"4",
"4",
"444",
"000044",
"34534539893",
"0390804980498409480",
"00000002998"]

=ERROR REPORT==== 3-Sep-2007::18:01:34 ===
Error in process <0.375.0> with exit value: {function_clause,[{numbers,print,[["098","03","9","80239802389","0","9","0983","890","03","3","4","3","4","4","444","000044","34534539893","0390804980498409480","00000002998"]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}

** exited: {function_clause,[{numbers,print,
[["098",
"03",
"9",
"80239802389",
"0",
"9",
"0983",
"890",
"03",
"3",
"4",
"3",
"4",
"4",
"444",
"000044",
"34534539893",
"0390804980498409480",
"00000002998"]]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
113>
View user's profile Send private message
michal
Posted: Mon Sep 03, 2007 1:12 pm Reply with quote
User Joined: 20 Jul 2006 Posts: 44 Location: London
Hi,
Rewrite function print as follows:

([L1 | L]) ->
io:format("~p~n", [L1]),
print(L);
print([]) ->
ok.

'end-of-list' in Erlang is noted as an empty list [].

Michal

_________________
http://www.erlang-consulting.com
View user's profile Send private message
Mazen
Posted: Tue Sep 04, 2007 8:44 am Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Hi Brett,
a few pointers:

1) Lists are actually denoted as "lists in a list" where each list is actually a list of 2 elements.
E.g:[ 1, [] ]. and [1] is the same thing.
or
[ 1, [ 2, []]] is the same as [1,2].

note that [] is *not* the same as [ [] ].

knowing this you can patternmatch on then the second element in a list is empty i.e. [].

2) You can patternmatch directly in the function header and you should always try to do this as much as possible since it is very effective (this does not include function guards). As michal shows you in his code, you patternmatch on the first element of a list, and tail recurse on the second one.

thus you can type:
Code:

print([L1 | L]) ->
     ...
     print(L);
print([]) ->
     ok.

which means that you in the function head directly bind L1 to the first element of the list. Note that this will also match when ever the list only consists of 1 element as well.

The reason you get your error is because you are patternmatching on a list with *exactly* 1 element OR the integer 0, which makes the code fail because it can't find a suitable function to run according to you arguments.

For some bedtime reading see:
1) http://www.erlang.org/doc/reference_manual/data_types.html#2.10
2) http://www.erlang.org/doc/reference_manual/patterns.html#3

Very Happy

/Mazen
View user's profile Send private message
brett hallett
Posted: Wed Sep 05, 2007 4:15 am Reply with quote
User Joined: 21 Aug 2007 Posts: 21
Thanks for the responses - accurate AND useful Cool

However now that I have a list thus
["999", "12", "345' ---etc ]

how do I convert this into a un-quoted list of integers ?

[ 999,12, 345, --- etc ].

I wish to sort the integer list , at the moment its a ascii list
and of course the sort order is not numeric sequence.

I've tried various "to_integer" functions to no avail.
View user's profile Send private message
Mazen
Posted: Wed Sep 05, 2007 8:16 am Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Not to serve you everything for "free", more fun if you find it yourself.

I suggest you take a look at the lists module in the documentation on how to traverse a list where you want to manipulate each element and/or order of the list.

Erlang have some built in functions to handle the type conversions. Take a look at the erlang module in the documentation and you will find functions that are called like "Something_to_Something" e.g. atom_to_list/1. This will, not very suprisingly convert an atom to a list.

Remember that a string in Erlang is defined as a list with acsii characters.

now you have everything you need to do what you wanted to do. Good luck! Very HappyVery Happy

1) lists: http://www.erlang.org/doc/man/lists.html
2) erlang: http://www.erlang.org/doc/man/erlang.html
View user's profile Send private message
brett hallett
Posted: Thu Sep 06, 2007 11:42 pm Reply with quote
User Joined: 21 Aug 2007 Posts: 21
Actually I have read the manuals, even the one on list!
But as its such a poor manual, I did not understand the relevence
of map & zip in solving my problem.
Manuals without EXAMPLE code are less than useful. Smalltalk manuals
suffer from the same problem.
( I realise you did'nt write the manual Smile

However, your comments did offer the hint required to suss out the answer, thanks.
Now I need to figure out Erlangs regexp facilities to replace the hidious "Txt2 =" line.

=====================================
-module(numbers3).

%% extract numerics from a mixed text line , sort ascending,
%% but retain any leading zeros.
%% based upon problem set by www.devx.com
%% eg "12cd 45erw 4rfr 22ss" => ["12","45","04","0022"]
%% then transform to [{4,"04"},{12,"12"},{22},{0022},{45,"45"}]

-export([ start/0 ]).

%% the print function 'pops' the head entry from the passed list

print( [ L1 | L]) ->
io:fwrite('~p~n', [L1]),
print(L);
print([]) -> ok.

start() ->
Txt =" 098m 03 r9 f8023982389f0m9KDKKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl dj99kl djkl d00000002998",
io:fwrite("Txt : ~s ~n", [Txt]),
Txt2 = string:tokens(Txt," abcdefghijklmnopqysruvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
%% Txt2 will contain a list of numeric ("text") tokens
Txt3 = lists:map(fun(X) -> list_to_integer(X) end, Txt2),
%% Txt3 contains a list of numerics ( not text) tokens
Txt5 = lists:zip(Txt3, Txt2),
%% Txt5 contains a list of tuples [{12,"12"},{333,"333"}
Txt4 = lists:sort(Txt5),
%% Txt4 contains sorted tuple list
print(Txt4).
Laughing Laughing
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum