Just trying to get my head round monads...
looking at this page at the moment: http://www.haskell.org/haskellwiki/Simple_monad_examples
at the bottom it asks what do these snippets resolve to:
Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
Why does this return Nothing? Because of the fail call?
Nothing >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
I understand this one.
-
Thanks all for confirming and explanation :)Tobi3– Tobi32012年05月06日 20:02:20 +00:00Commented May 6, 2012 at 20:02
3 Answers 3
As always in Haskell, you can usually understand some code by inlining and term rewriting:
We have:
Prelude> Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
Nothing
The most important thing we need is the definition of fail and >>= for the Maybe monad, given as:
instance Monad Maybe where
(Just x) >>= k = k x
Nothing >>= _ = Nothing
(Just _) >> k = k
Nothing >> _ = Nothing
return = Just
fail _ = Nothing
so we have:
Just 0 >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
-- by definition of >>=
(\ x -> if (x == 0) then fail "zero" else Just (x + 1) ) 0
-- by definition of fail
(\ x -> if (x == 0) then Nothing else Just (x + 1) ) 0
-- beta reduce
if 0 == 0 then Nothing else Just (0 + 1)
-- Integer math
if True then Nothing else Just 1
-- evaluate `if`
Nothing
and there you have it.
Comments
The behavior of fail depends on the monad. In the Maybe monad, fail returns Nothing.
instance Monad Maybe where
return = Just
(Just x) >>= k = k x
Nothing >>= _ = Nothing
fail _ = Nothing
However, in many other monads fail translates to error, since that is the default implementation. The monads which provide their own fail are usually the ones in the MonadPlus class, where you can have fail return mzero, which is Nothing in the Maybe monad.
In practice, I don't recommend using fail since it's so unclear what it will do. Instead, use the appropriate failure mechanism of the monad you're in, whether that's mzero, throwError or something else.
Comments
Yes, because of the fail call. Look at how Maybe is an instance of the Monad typeclass:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Maybe.html#Maybe
fail _ = Nothing