为什么haskell会在>>中评估a? B'

时间:2012-12-15 12:51:26

标签: haskell functional-programming operators monads

>> haskell中Monads的运算符通常定义为

(>>) :: m a -> m b -> m b
a >> b = a >>= \_ -> b

它可以用来打印像

这样的东西
main = putStr "foo" >> putStrLn "bar"

为什么编译器不会优化putStr "foo"的值而只评估putStrLn "bar"?它不需要它,为什么要计算呢?

3 个答案:

答案 0 :(得分:10)

正如克里斯所说,这取决于monad。 IdentityReader不会评估>>前面的部分,因为他们不需要它来计算结果。其他monad,例如WriterMaybeEitherStateIO

我们以Maybe为例。 >>=定义为

Nothing  >>= _  = Nothing
(Just x) >>= f  = f x

因此,如果我们扩展>>,我们就会

Nothing  >> _  = Nothing
(Just x) >> y  = y

所以Maybe必须评估>>前面的内容,看看结果是Nothing还是y

IO是以某种方式定义的,以便评估操作是否需要其结果(否则将无法使用)。

答案 1 :(得分:6)

咦?当然它需要putStr "foo"的值。它在>>=中进行了评估 - 如果您想将monads视为操作,则只会删除操作的结果,而不是操作本身。

例如在解析器中,这意味着丢弃刚刚解析的序列 - 但它仍然被解析,因此光标仍然向前移动。

答案 2 :(得分:6)

这取决于monad。在IO中进行评估。在Identity中,第一个未被评估:

> import Control.Monad.Identity
> import Control.Monad.Trace
> let x = trace "x" $ return () :: Identity ()
> let y = trace "y" $ return () :: Identity ()
> runIdentity $ x >> y
y
()
相关问题