简体   繁体   English

为什么haskell评估a >> b?

[英]Why does haskell evaluate a in a >> b?

The >> operator for Monads in haskell is often defined as haskell中Monads的>>运算符通常定义为

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

It can be used to print things like 它可以用来打印像

main = putStr "foo" >> putStrLn "bar"

Why does the compiler not optimize away the value of putStr "foo" and just evaluate putStrLn "bar" ? 为什么编译器没有优化putStr "foo"的值而只评估putStrLn "bar" It doesn't need it so why compute it? 它不需要它,为什么要计算呢?

As Chris said, it depends on the monad. 正如克里斯所说,这取决于monad。 Identity or Reader won't evaluate the part in front of >> , because they don't need it to compute the result. IdentityReader不会评估>>前面的部分,因为它们不需要它来计算结果。 Other monads, like Writer , Maybe , Either , State or IO will. 其他monad,如WriterMaybeEitherStateIO会。

Let's take Maybe as an example. 我们以Maybe为例。 >>= is defined as >>=定义为

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

So if we expand >> we get 所以,如果我们扩展>>我们得到

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

So Maybe must evaluate what's in front of >> to see if the result will be Nothing or y . 所以Maybe必须评估>>前面的内容,看看结果是否为Nothingy

IO is purposely defined in a way so that the action is evaluated whether its result is needed or not (otherwise it would be just impossible to use). IO是以某种方式有目的地定义的,以便评估操作是否需要其结果(否则将无法使用)。

Huh? 咦? Of course it needs the value of putStr "foo" . 当然它需要putStr "foo"的值。 It's evaluated in >>= - only the result of the action is thrown away, not the action itself if you want to think of monads as actions. 它在>>=进行评估 - 只有动作的结果被抛弃,而不是动作本身,如果你想将monads视为动作。

For example in a parser, that would mean throwing away the just parsed sequence - but it was still parsed, so the cursor is still being moved forward. 例如,在解析器中,这意味着丢弃刚刚解析的序列 - 但它仍然被解析,因此光标仍然向前移动。

It depends on the monad. 这取决于monad。 In IO is is evaluated. 在IO中进行评估。 In Identity the first is not evaluated: 在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
()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM