I've just started to learn Haskell and I was told that Haskell is lazy, i.e. it does as little work as possible in evaluating expressions, but I don't think that's true.
Consider this:
und :: Bool -> Bool -> Bool
und False y = False
und y False = False
non_term x = non_term (x+1)
The evaluation of und (non_term 1) False
never terminates, but it's clear that the result if False.
Is there a way to implement und
(i.e. and
in German) correctly (not just partially as above) so that both
und (non_term 1) False
and
und False (non_term 1)
return False?
You can write a complete definition for
und
that will work on non-terminating expressions... sort ofTo make this work, you need your own definition of
Bool
that makes explicit the delay in any computation:Then whenever you define a value of type
Bool
, you have to constrain yourself to co-recursion, where the delays are made explicit with theDelay
constructor, rather than via recursion, where you have to evaluate a sub-expression to find the constructor for the top-level return value.In this world, a non-terminating value could look like:
Then
und
becomes:which works just fine:
Following up on dfeuer's comment, it looks like what you're looking for can be done with
unamb