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?