I have this Erlang code:
not lists:any(fun(Condition) ->Condition(Message) end, Conditions).
Can anyone please explain the entire statement in layman's terms? For your information Condition is a function, Conditions is an array. What does fun(Condition) ->Condition(Message) end mean? As well as meaning of not lists:any.
fun(Condition) ->Condition(Message) end
is a lambda function that applies the function Condition to the value of Message (taken as a closure on the surrounding code).
lists:any
is a function that takes a predicate and a list of values, and calls the predicate on each value in turn, and returns the atom true if any of the predicate calls do.
Overall, the result is the atom true if none of the Condition functions in the list Conditions return true for the Message value.
EDIT -- add documentation for lists:any
any(Pred, List) -> bool()
Types:
Pred = fun(Elem) -> bool()
Elem = term()
List = [term()]
Returns true if Pred(Elem) returns true for at least one element Elem in List.
Condition is something that takes a message and returns a boolean if it meets some criteria.
The code goes through the list of conditions and if any of them say true then it returns false, and if all of them say false it says true.
Roughly translated to verbose pseudo-Python:
def not_lists_any(Message,Conditions):
for Condition in Conditions:
if Condition(Message):
return False
return True
One step behind syntax and stdlib description which you have in other answers:
This code looks very much like an Erlang implementation of chain-of-responsibility design pattern. The message (in OOP sense of the word) "traverses" all possible handlers (functions from Conditions array) until someone can handle it. By the author's convention, the one which handles the message returns true (otherwise false), so if nobody could handle the message the result of your expression as a whole is true:
% this is your code wrapped in a function
dispatch(Message, Handlers) ->
not lists:any(fun(Condition) ->Condition(Message) end, Handlers).
It may be used like this:
CantHandle = dispatch(Event, Handlers),
if CantHandle->throw(cannot_handle); true->ok end.
Related
getting an error when I try to run this line of code and I can't figure out why
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else true
As Tyler Hartwig says a for loop cannot return a value except unit.
On the other hand, inside a list comprehension or a seq Computation Expression you can use for to yield the values and then test if the one you are looking for exists:
let validCol column value : bool =
seq { for i in 0..8 do yield sudokuBoard.[i,column] }
|> Seq.exists value
|> not
In F#, the last call made is what is returned, you have explicitly declared you are returning a bool.
The for loop is unable to return or aggregate multiple values, bun instead, returns unit.
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else
true
Here, you'll need to figure out how to aggregate all the bool to get your final result. I'm not quite sure what this is supposed to return, or I'd give an example.
It looks like you are looking for a short-cut out of the loop like in C# you can use continue, break or return to exit a loop.
In F# the way to accomplish that with performance is to use tail-recursion. You could achieve it with while loops but that requires mutable variables which tail-recursion doesn't need (although we sometimes uses it).
A tail-recursive function is one that calls itself at the very end and doesn't look at the result:
So this is tail-recursive
let rec loop acc i = if i > 0 then loop (acc + i) (i - 1) else acc
Where this isn't
let rec loop fib i = if i < 1 then 1 else fib (i - 1) + fib (i - 2)
If F# compiler determines a function is tail-recursive the compiler applies tail-recursion optimization (TCO) on the function, basically it unrolls it into an efficient for loop that looks a lot like the loop would like in C#.
So here is one way to write validCol using tail-recursion:
let validCol column value : bool =
// loops is tail-recursive
let rec loop column value i =
if i < 9 then
if sudokuBoard.[i,column] = value then
false // The value already exists in the column, not valid
else
loop column value (i + 1) // Check next row.
else
true // Reach the end, the value is valid
loop column value 0
Unfortunately; F# compiler doesn't have an attribute to force TCO (like Scala or kotlin does) and therefore if you make a slight mistake you might end up with a function that isn't TCO. I think I saw GitHub issue about adding such an attribute.
PS. seq comprehensions are nice in many cases but for a sudoku solver I assume you are looking for something that is as fast as possible. seq comprehensions (and LINQ) I think adds too much overhead for a sudoku solver whereas tail-recursion is about as quick as you can get in F#.
PS. In .NET 2D arrays are slower than 1D arrays, just FYI. Unsure if it has improved with dotnet core.
I am trying to verify my code in Dafny and I encountered a problem:
I have a method that is iterating over a sequence and changes it. The method changes the sequence according to the elements in the sequence. I would like to add a post condition like this: "if the elements in the sequence are X then something should happen". The problem is that the method changes the set (adds element etc.) and I want to check the condition of the original sequence. Is there an elegant way of doing that in Dafny? (The only way I could think of right now is keeping global var of the original condition of the sequence, but I am looking for the right way of doing that).
Code example:
method changeSeq(p: class1, s: seq<class1>)
ensures |s| == 10 ==> p in s
{
if (|s| == 10){
s := s + [p];
}
}
In the code, I want the post condition to check original s stat, and not its stat after we changed it.
you can use old for old value of a variable like s == old(s).
Here is one example: http://rise4fun.com/Dafny/fhQgD
From Dafny Documentation 22.18. Old Expressions
OldExpression_ = "old" "(" Expression(allowLemma: true, allowLambda: true) ")"
An old expression is used in postconditions. old(e) evaluates to the value expression e had on entry to the current method. Note that old only affects heap dereferences, like o.f and a[i]. In particular, old has no effect on the value returned for local variables or out-parameters.
I am trying to see if a letter exists in a list, i am currently doing like the following
sortedlist(Text)-> freq(lists:sort(Text)).
freq(List) -> freq (List, [], []).
freq(List, Freq, CheckedLetters) when length(List) > 0 ->
[CurrHead|T]= List,
Checked = lists:member(CurrHead,CheckedLetters),
case Checked of
false -> CheckedLetters++[CurrHead],
freq(T,Freq++[{CurrHead,count(CurrHead, List)}],CheckedLetters);
true -> freq(T,Freq,CheckedLetters)
end;
freq([],Freq,CheckedLetters)-> Freq.
List contains user entered letters
CheckedLetters is an empty list, that will keep track of the already examined letters
But I am receiving the following erlang exception at the case-statement line (the lines with **).
error: no match of right hand side value []
What is the problem here? I am been blindy staring at those lines.
The end condition is missing in your recursive function. So when list become empty (each time you recall the function with the tail it is getting smaller), the match [CurrHead|T]= List, fails with error.
You have to add a clause to manage the end of recursion:
freq([], Freq, CheckedLetters) when length(List) > 0 ->
{Freq, CheckedLetters};
freq(List, Freq, CheckedLetters) when length(List) > 0 ->
[CurrHead|T]= List,
Checked = lists:member(CurrHead,CheckedLetters),
case Checked of
true -> CheckedLetters++[CurrHead],
freq(T,Freq++[{CurrHead,count(CurrHead, List)}],CheckedLetters);
false -> freq(T,Freq,CheckedLetters)
end;
I think you will have also to review the inside operation, I doubt it is doing what you expect. in particular the line CheckedLetters++[CurrHead], has no effect.
[edit]
Don't forget that variables are not mutable in erlang. So the line CheckedLetters++[CurrHead] simply evaluates a new list and forget the result (in fact I am not sure it does anything since you do not bound this evaluation to any variable, and the compiler knows it).
I guess that what you want to do is:
case Checked of
true ->
freq(T,Freq++[{CurrHead,count(CurrHead, List)}],CheckedLetters++[CurrHead]);
false ->
freq(T,Freq,CheckedLetters)
end;
Next you should have a look at Freq++[{CurrHead,count(CurrHead, List)}], I think it isn't correct.
The only piece of code in that block that could error: no match of right hand side value [] is [CurrHead|T]= List, as Steve Vinoski said. Likely there is some scenario where List is an empty list instead of a list of letters.
Also, the last line in the code block you shared:
case Checked == false of
...
end
Can be simplified to:
case Checked of
true ->
...
false ->
...
end
Since Checked is the return value of lists:member/2, and lists:member/2 is guaranteed to return a boolean, you can safely match directly on the true and false atoms.
lists:member/2 documentation: http://erlang.org/doc/man/lists.html#member-2
I am new to Erlang. I have a project for school which uses an ets:table.
But before I want to get some data out of the ets:table, I want to use an if-structure for checking out the table if it isn't empty.
if
ets:first(Cal) =/= '$end_of_table' ->
Event = ets:first(Cal),
{TimeAtStart, Ref} = Event,
NowTime = now(),
Ms = timer:now_diff(NowTime, TimeAtStart)div 1000
end,
Now this gives me an error: Illegal guard expression.
I don't know what I'm doing wrong, please help.
With friendly regards
Daan
if expect a guard sequence. so it fails. You could make the test before the if, and use the result, but with your code, when you get '$end_of_table', it will fails also since you have not true statement.
I recommend to use a case statement for your code:
case ets:first(Cal) of
'$end_of_table' ->
{error,no_entry};
{TimeAtStart, _Ref} ->
{ok,timer:now_diff(now(), TimeAtStart)div 1000}
end,
The illegal guard statement comes from calling the ets:first(Cal) function from within an if statement guard. so if ets:first(Cal) =/= '$end_of_table' -> is not going to compile correctly. Guard statements only have a small set of functions that can be used, read about them here.
Also if statements are a little different in Erlang vs. other languages. One clause at least must evaluate to true. The Documentation on if statements explains this behavior, and how an error is thrown if no clause evaluates to true.
So moving the ets:first(Cal) outside of the if statement and adding a catch all true case to your code, should work:
Res = ets:first(Cal),
if
Res =/= '$end_of_table' ->
Event = ets:first(Cal),
{TimeAtStart, Ref} = Event,
NowTime = now(),
Ms = timer:now_diff(NowTime, TimeAtStart)div 1000;
true -> ok %% you need a default clause
end,
However, if it was me doing my school project, I would try to use the ets:info function to check the size of the table, and do it inside of a case statement. Checkout the Documentation on the ets:info function, and the case statement.
Just FYI: I don't think I have used an if statement the entire time I have been programming in Erlang.
I want to learn Erlang and in the book I have the exercise:
Write a module boolean.erl that takes logical expressions and Boolean values (represented
as the atoms true and false) and returns their Boolean result. The functions
you write should include b_not/1, b_and/2, b_or/2, and b_nand/2. You should not use
the logical constructs and, or, and not, but instead use pattern matching to achieve your
goal.
Test your module from the shell. Some examples of calling the exported functions in
your module include:
bool:b_not(false) ⇒ true
bool:b_and(false, true) ⇒ false
bool:b_and(bool:b_not(bool:b_and(true, false)), true) ⇒ true.
So the best solution I came up with so far is:
-module(b).
-export([b_not/1,b_and/2,b_or/2]).
b_not(false) -> false /= true.
%%%
b_and(false, false) -> false;
b_and(X, Y) -> X == Y.
%%%
b_or(true, true) -> true;
b_or(X, Y) -> X /= Y.
How to solve the last example, I really don`t get it. Any help?
Thanks.
I disagree a little with what #hdima said. The goal of this exercise is to practise pattern matching and not use any operators. The best way with pattern matching is to write down every case. So for b_or what are the different possible cases for the arguments? There are 4: true, true; true, false; false, true; and false, false. So just write down each case as a separate clause returning the correct value:
b_or(true, true) -> true;
b_or(true, false) -> true;
b_or(false, true) -> true;
b_or(false, false) -> false.
So looking at this answer you could be thinking well as many cases are the same why not optimise this to:
b_or(false, false) -> false;
b_or(_, _) -> true.
_ is the don't care variable which matches anything and never gets bound. Well, both version behave the same if called with boolean values BUT they behave differently if called with non-boolean values. In this case the second returns true while the first one generates an exception. Usually it is better to generate an exception on bad input rather than let it pass and return a misleading answer, so the first alternative is a better solution.
Writing b_and (and b_xor) is left to you.
Sorry if this was a bit long but pattern matching can take some getting used to. The concept of writing down what you expect and not how to test for it is different from what is common in OO and imperative languages. (I give courses and this is a common hurdle)
If you limited only to pattern matching b_not/1 should looks like this:
b_not(false) -> true;
b_not(true) -> false.
Try to use this idea for the other functions.
Hint: for the other functions you don't need to write clauses for every possible case.