Folding, function composition, monads, and laziness, oh my?

笑着哭i 提交于 2019-11-30 06:39:15

It depends on which monad you're working with, and how its (>>=) operator is defined.

In the case of Maybe, (>>=) is strict in its first argument, as Daniel Fischer explained.

Here are some results for a handful of other monads.

> :set -XNoMonomorphismRestriction
> let foo = (const (return 42) <=< undefined <=< return) 3
> :t foo
foo :: (Num t, Monad m) => m t

Identity: Lazy.

> Control.Monad.Identity.runIdentity foo
42

IO: Strict.

> foo :: IO Integer
*** Exception: Prelude.undefined

Reader: Lazy.

> Control.Monad.Reader.runReader foo "bar"
42

Writer: Has both a lazy and a strict variant.

> Control.Monad.Writer.runWriter foo
(42,())
> Control.Monad.Writer.Strict.runWriter foo
*** Exception: Prelude.undefined

State: Has also both a strict and a lazy version.

> Control.Monad.State.runState foo "bar"
(42,"*** Exception: Prelude.undefined
> Control.Monad.State.Strict.runState foo "bar"
*** Exception: Prelude.undefined

Cont: Strict.

> Control.Monad.Cont.runCont foo id
*** Exception: Prelude.undefined

The bind for Maybe is strict in the first argument.

Just v >>= f = f v
Nothing >>= f = Nothing

So when you try

Just v >>= undefined >>= \_ -> Nothing

you hit

undefined v >>= \_ -> Nothing

and the implementation needs to find out whether undefined v is Nothing or Just something to see which equation of (>>=) to use.

On the other hand,

Nothing >>= undefined

determines the result without looking at the second argument of (>>=).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!