Consider a function choose
in Curry programming language with the specification that "(choose xs)
non-deterministically chooses one element from the list xs
".
I'd implement it straighforwardly through two alternative non-deterministic rules:
choose :: [a] -> a
choose x:_ = x
choose _:xs = choose xs
But in /usr/lib/curry-0.9.11/Success.curry from Muenster Curry Compiler, it is defined with a helper function:
choose (x:xs) = choosep x xs
where choosep x [] = x
choosep x (_:_) = x
choosep _ (x:xs) = choosep x xs
What could be the advantages (if any) of the definition from the compiler supplied module? Are the 2 definitions completely equivalent (even in some tricky cases with non-determinism and undefined values)?.. Is one of them more efficient in some cases?
ADDED: Deeper consideration
cthom06 (Thanks!) has correctly pointed out that my definition would cause hitting the undefined value in much more cases (because we would try to call this function with an empty-list argument once per each our "top-level" call with an initially non-empty list argument). (Hm, why haven't I noticed this consideration right away?..) That is less efficient.
But I wonder: are there any semantic differences? May the difference be important in some tricky contexts?
We see that the difference between the two definitions--in the case of non-empty lists--basically boils down to the difference between two potential definitions for id
:
my definition is like defining id
as:
id x = x
id _ = undefined
and their definition is like definig id
the normal way:
id x = x
(So, here the straightforwardness is reverted.)
In which contexts can it be important?
id
with one ruleid x = x
or with an extra bogus rule:id x = x
andid _ = undefined
? I wonder: are there tricky cases when the semantics can change? – Epistylechoosep
some naming convention for helper functions? – Epistyleid x = x
andid _ = undefined
will lead to a not-deterministic id. Half the times it will give x and the other halve undefined. I am not sure, I don't have the compiler here. But it feels really awkward to write. – Mooneyp x = 1
andp _ = error "boom"
then solve for a constraint:p :=: 2
and it will go boom. curryOnline – Mooneycyi
from Muenster Curry Compiler, if I enterp :=: 2
, I get ":=: is undefined". What is:=:
? – Epistyle((x || y) && x) =:= True where x, y free
will give all x,y which conforms to the equation. (x || y) && x == True – Mooneyid x = x
is different from:id x = x
andid _ = undefined
. This gives me forid 1
1 and then an error. The semantics are changed, because if I rearrange the two equations to:id _ = undefined
andid x = x
. I never get a result from the second equation.id 1
gives just an error.undefined = error "undefined"
. On kics2 there is no undefined. – Mooneyid
. They only differ in the error messages,but this can't count as a semantic diff – Epistyleid x = x
differs fromid x = x and id _ = undefined
. – Mooneyundefined = failed
then there is no difference, between the two definitions ofid
. So you are right, because I had the definition of undefined wrong.error
is something special. Thanks fyi. – Mooneyhead (a : xs) = a
behaves ashead (x:xs) = x
andhead [] = failed
. But how should we interpreterror
? – Mooney