I'm reading a revealing example of using a bind operator:
Just 5 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
returns Just 6
.
I'm confused by the behaviour of fail
and its usefulness in the example.
When looking at the code I thought fail "zero"
may have a meaning:
- program never gets to that point
- laziness
- something else.
Then I realised that after a type cohesion, an exception becomes Nothing
(documented here). Still confusing for me that without type enforcement fail
is just an error in program.
Prelude> fail "zero" :: Maybe Int
Nothing
Prelude> fail "abc" :: [Int]
[]
Prelude> fail "zero"
*** Exception: user error (zero)
My question is about usefulness of fail "zero"
in this example.
Is it a proper reading (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
attempts to be simple case for a -> Maybe a
function?
What prevents us from using (\ x -> if (x == 0) then Nothing else Just (x + 1) )
if we just needed an illustration of a -> Maybe a
?
I found this version below a much easier and shorter way to grasp same example.
Prelude> g x = if (x == 0) then Nothing else Just (x + 1)
Prelude> Just 0 >>= g
Nothing
Prelude> Just 1 >>= g
Just 2