For each throws error in erlang - erlang

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)

Related

Why does lists:flatten/2 does not work fine on Erlang script?

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).

Erlang ** exception error: no function clause matching

Hi guys I have the makings of a parser for a Theorem Prover. I have a module which previously tokenises the string so im inputting: [{bracket,open},{prop,a},{logicOp,'and'},{prop,b},{bracket,close}] to a parser which has an calls an inner function. here is the code:
parse([])-> [];
parse(FullList) ->
parseClauses(FullList,[],[]).
parseClauses([{bracket, open}| RestOfList], StackList, ParsedList) ->
parseClauses(RestOfList,
StackList ++ [{bracket, open}],
ParsedList);
parseClauses([{prop, Any},{logicOp, Any}| RestOfList], StackList, ParsedList) ->
parseClauses(RestOfList,
StackList ++ [{logicOp, Any},{prop, Any}],
ParsedList);
parseClauses([{bracket, close}, {logicOp, Any}| RestOfList],StackList,ParsedList) ->
parseClauses(RestOfList,
StackList ++ [{bracket, close}],
[{logicOp, Any}] ++ ParsedList);
parseClauses([{bracket, close}|RestOfList], StackList, ParsedList) ->
parseClauses(RestOfList,
StackList++[{bracket, close}],
ParsedList);
parseClauses([], Stack, Parsed) -> Parsed ++ Stack.
run the code on terminal like so and get error:
tokeniser:parse([{bracket,open},
{prop,a},
{logicOp,'and'},
{prop,b},
{bracket,close}]).
** exception error: no function clause matching tokeniser:parseClauses([{prop,a},{logicOp,'and'},{prop,b},{bracket,close}],
[{bracket,open}],
[])
From the error message, you can tell that the function is being called like this:
tokeniser:parseClauses([{prop,a},{logicOp,'and'},{prop,b},{bracket,close}],
[{bracket,open}],
[])
This almost matches this clause:
parseClauses([{prop, Any},{logicOp, Any}| RestOfList], StackList, ParsedList) ->
But since Any is used twice in the argument list, this clause only matches when the two values are the same. In this call, they are different: a and 'and'.
You could change the two occurences of Any to something else, e.g. Prop and LogicOp, and the clause would accept two different values.

erlang substr - no function clause

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.

get the last value of table [duplicate]

This question already has answers here:
Mnesia returns {aborted, no_transaction}
(2 answers)
Closed 10 years ago.
I have a table person which has this record :
-record(person, {id, firstname, lastname, address}).
I want to develop a function which will retreive the last id of this table
I try with this function :
get_userId() ->
Q = qlc:q([{X#person.id} || X <- mnesia:table(person)
]),
case do(Q) of
[{H}] ->
{ok, H};
[] ->
{error, notfound}
end.
And I do the test with this code
test()->
case get_userId() of
{ok, H}->io:format("~s~n",[H]);
[] ->
{error, notfound}
end.
but I have error when I make the test
2> model:test().
** exception error: no case clause matching [{238},
{82},
{76},
{257},
{141},
{2},
{315},
{336},
{275},
{88},
{326},
{211},
{81},
{333},
{351},
{214},
{64},
{265},
{210},
{90},
{302},
{98},
{212},
{197},
{194},
{132},
{226},
{3},
{...}|...]
in function model:get_userId/0
in call from model:test/0
The problem is that the value returned from do(Q) is a list containing many elements. You see them listed in the error report. However patterns which you match this value against only will match a list with one element, [{H}], the list with no elements, the empty list []. Therefore you get a case_clause error as none of the clauses match.

Exception error in Erlang

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.

Resources