Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Understanding Monads

Tags:

haskell

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.

like image 870
Tobi3 Avatar asked Jul 09 '26 15:07

Tobi3


2 Answers

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.

like image 73
Don Stewart Avatar answered Jul 11 '26 17:07

Don Stewart


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.

like image 36
hammar Avatar answered Jul 11 '26 17:07

hammar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!