Tobi3
Tobi3

Reputation: 147

Haskell Understanding Monads

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.

Upvotes: 2

Views: 313

Answers (3)

Don Stewart
Don Stewart

Reputation: 137947

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.

Upvotes: 8

hammar
hammar

Reputation: 139840

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.

Upvotes: 4

efie
efie

Reputation: 544

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

Upvotes: 2

Related Questions