Learning erlang and just a bit confused with what I'm trying to do in the following code:
start() ->
Lst = string:tokens("Hello,How,Are,You!Today",",!"),
Result = [string:substr(Lst, ".!", len(Lst))],
Result.
I get the following error: exception error: no function clause matching string:substr(["Hello","How","Are","You","Today"],".!",5)
string:substr/3 takes integers in both its second and third argument:
10> [string:substr(Lst, 1, length(Lst))].
[["Hello","How","Are","You","Today"]]
11> [string:substr(Lst, 3, length(Lst))].
[["Are","You","Today"]]
You're passing the string ".!" as the second argument, which is why you're getting a function clause error.
Related
I'm trying to implement the a split method in Erlang that is supposed to split a string like "i am on the mountain top" into a list like ["i","am","on","the","mountain","top"].
Here is my code (exercise.erl):
-module(exercise).
-import(oi,[read/1]).
-export([split/4]).
split(Text,_,Result,_) when Text == [] -> Result;
split([Head|Tail],Separator,Result,WordSummer) when Head == Separator ->
split(Tail,Separator,[Result|lists:flatten(WordSummer)],[]);
split([Head|Tail],Separator,Result,WordSummer) ->
split(Tail,Separator,Result,[WordSummer|Head]).
The problem I'm having is that when calling my exported function I get the following error:
9> c(exercise).
{ok,exercise}
10> exercise:split("sdffdgfdg dgdfgfg dgdfg dgdfgd dfgdfgdfgtrty hghfgh",$ ,[],[]).
** exception error: no function clause matching lists:do_flatten(103,[]) (lists.erl, line 627)
in function lists:do_flatten/2 (lists.erl, line 628)
in call from exercise:split/4 (exercise.erl, line 9)
11>
How can I solve this?
Two things:
The [WordSummer|Head] in the last line is creating an improper list because Head is an integer (one character of the input string). This is causing the error you're seeing. You probably meant [WordSummer, Head].
[Result|lists:flatten(WordSummer)] is creating a nested list instead of a list of strings. To append one item to a list, use ++ and wrap the right side in a list: Result ++ [lists:flatten(WordSummer)]
Final code:
split(Text,_,Result,_) when Text == [] -> Result;
split([Head|Tail],Separator,Result,WordSummer) when Head == Separator ->
split(Tail,Separator,Result ++ [lists:flatten(WordSummer)],[]);
split([Head|Tail],Separator,Result,WordSummer) ->
split(Tail,Separator,Result,[WordSummer, Head]).
Test:
1> c(exercise).
{ok,exercise}
2> exercise:split("sdffdgfdg dgdfgfg dgdfg dgdfgd dfgdfgdfgtrty hghfgh",$ ,[],[]).
["sdffdgfdg","dgdfgfg","dgdfg","dgdfgd","dfgdfgdfgtrty"]
There's still a bug where the last segment is being ignored. I'll let you figure that out (hint: you need to consider WordSummer in the first clause of the function).
I want to send all of the list content over TCP but i get some error
Code that send the list data
sendHistory(To, List) ->
lists:foreach(fun(#data{timestamp = T, data = D})->
gen_tcp:send(To, T),
gen_tcp:send(To, D)
end, List).
And I get this error.
Error in process <0.65.0> with exit value:
{function_clause,[{lists,foreach,
[#Fun<storage.0.129058542>,
{data,["1495971980"],
["\n\t",
["Jaam: ",
["Kuressaare linn"],
" Temperature: ",[]],
"\n\t",...]}],
[{file,"lists.erl"},{line,1337}]},
{storage,loop,4,[{file,"storage.erl"},{line,61}]}]}
The following line clause in your previous code is creating an improper list:
addToListIfNotAlreadyIn(New, [Old]) -> {[New | Old], ok};
You probably meant to write:
addToListIfNotAlreadyIn(New, [Old]) -> {[New, Old], ok};
The error message means that lists:foreach/2 was called with a second argument which was not a list. Since lists:foreach/2 recursively calls itself with the tail of the list after applying the function to the head, if an improper list is passed to the function, it will end up calling itself with a non-list argument on the last iteration:
1> lists:foreach(fun(X) -> ok end, [1, 2, 3 | 4]).
** exception error: no function clause matching lists:foreach(#Fun<erl_eval.6.118419387>,4) (lists.erl, line 1337)
i am a beginner of erlang.
this is my code:
-module(squsum).
-export([main/0]).
ssum(1) -> 1;
ssum(N) -> N*N + ssum(N-1).
main() ->
{_,T} = io:fread("","~d"),
io:fwrite("~p~n",[ssum(T)]).
why will it have such a problem?
** exception error: an error occurred when evaluating an arithmetic expression
in function squsum:ssum/1 (squsum.erl, line 5)
in call from squsum:main/0 (squsum.erl, line 9)
T is a list containing the value, I guess it is the symmetric point of view of IO:fwrite. so simply use:
main() -> {ok,[T]} = io:fread("","~d"), io:fwrite("~p~n",[ssum(T)]).
I'm not too familiar with erlang, but if it is at all possible for T to be negative, then your recursive function would never end.
Similarly, if T=0, the function would never end.
This is really on comment on Pascal's answer: just to add that io:fread/2 returns a list of the terms specified in the format string --- even if the format string has just one term, it returns a list with one element.
The erlang documentation is quite good. io:fread/2 is at http://erlang.org/doc/man/io.html#fread-2
I've found in module rpc function pmap. And I've stuck when tried to use it.
The first question - does it requires connection with other nodes, or it would performs as lists:map if there is no connection to other nodes?
I've tried to execute pmap without connection to other nodes, but got exception:
7> rpc:pmap( { erlang, '+' }, [], [[1,1],[2,3]] ).
** exception exit: badrpc
in function rpc:check/2 (rpc.erl, line 745)
After that - I've launched another local node and connected it with current. But still get the same error.
Please provide me how to use rpc:pmap correctly.
Thanks
P.S.
Following code works expectedly (returns result 3):
70> erlang:apply( erlang, '+', [1,2] ).
3
71> erlang:'+'(1,2).
3
The rpc:map({Module, Function},ExtraArgs,List1) evaluates apply(Module, Function, [Elem|ExtraArgs]), for every element Elem in List1, in parallel.
So the right syntax using erlang:'+' is:
1> rpc:pmap( { erlang, '+' }, [2], [1,2,3] ).
[3,4,5]
2>
which evaluates [1+2,2+2,3+2]
the syntax rpc:pmap( { lists, sum }, [], [[1,2],[4,5]] ) will evaluate [1+2,4+5] and return
[3,9]
Pascal
So I've been using Erlang for the last eight hours, and I've spent two of those banging my head against the keyboard trying to figure out the exception error my console keeps returning.
I'm writing a dice program to learn erlang. I want it to be able to call from the console through the erlang interpreter. The program accepts a number of dice, and is supposed to generate a list of values. Each value is supposed to be between one and six.
I won't bore you with the dozens of individual micro-changes I made to try and fix the problem (random engineering) but I'll post my code and the error.
The Source:
-module(dice2).
-export([d6/1]).
d6(1) ->
random:uniform(6);
d6(Numdice) ->
Result = [],
d6(Numdice, [Result]).
d6(0, [Finalresult]) ->
{ok, [Finalresult]};
d6(Numdice, [Result]) ->
d6(Numdice - 1, [random:uniform(6) | Result]).
When I run the program from my console like so...
dice2:d6(1).
...I get a random number between one and six like expected.
However when I run the same function with any number higher than one as an argument I get the following exception...
**exception error: no function clause matching dice2:d6(1, [4|3])
... I know I I don't have a function with matching arguments but I don't know how to write a function with variable arguments, and a variable number of arguments.
I tried modifying the function in question like so....
d6(Numdice, [Result]) ->
Newresult = [random:uniform(6) | Result],
d6(Numdice - 1, Newresult).
... but I got essentially the same error. Anyone know what is going on here?
This is basically a type error. When Result is a list, [Result] is a list with one element. E.g., if your function worked, it would always return a list with one element: Finalresult.
This is what happens (using ==> for "reduces to"):
d6(2) ==> %% Result == []
d6(2, [[]]) ==> %% Result == [], let's say random:uniform(6) gives us 3
d6(1, [3]) ==> %% Result == 3, let's say random:uniform(6) gives us 4
d6(0, [4|3]) ==> %% fails, since [Result] can only match one-element lists
Presumably, you don't want [[]] in the first call, and you don't want Result to be 3 in the third call. So this should fix it:
d6(Numdice) -> Result = [], d6(Numdice, Result). %% or just d6(Numdice, []).
d6(0, Finalresult) -> {ok, Finalresult};
d6(Numdice, Result) -> d6(Numdice - 1, [random:uniform(6) | Result]).
Lesson: if a language is dynamically typed, this doesn't mean you can avoid getting the types correct. On the contrary, it means that the compiler won't help you in doing this as much as it could.