它说的是陈述的顺序不影响评估标准。正如@chi 在 IO monad 中指出的那样,效果按顺序排列,但它们的评估顺序仍然未知。一个使概念清晰的单子示例:
test = do
x <- Just (2 + undefined)
y <- Nothing
return (x + y)
在 ghci 中:
λ> test
Nothing
上面的代码有三个语句。它可以脱糖成以下形式:
Just (2 + undefined) >>= \x -> Nothing >>= \y -> return (x + y)
现在因为(>>=)
是左关联的,它会被这样评估:
(Just (2 + undefined) >>= \x -> Nothing) >>= \y -> return (x + y)
请注意,Maybe
monad 是这样定义的:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing -- A failed computation returns Nothing
(Just x) >>= f = f x -- Applies function f to value x
将值(2 + undefined)
应用于函数\x -> Nothing
将导致Nothing
. 2 + undefined
由于 Haskell 之后的惰性求值策略,该表达式未求值。
现在我们有一个简化的形式:
Nothing >>= \y -> return (2 + undefined + y)
查看它的Monad
实例,您可以看到这将产生Nothing
,因为Nothing >>= _ = Nothing
. 如果参数是严格的怎么办:
test = do
!x <- Just (2 + undefined)
y <- Nothing
return (y + x)
演示ghci
:
λ> test
*** Exception: Prelude.undefined
如果我们遵循严格的评估程序,那么您可以看到顺序实际上很重要。但是在惰性设置中,语句的顺序并不重要。因此维基声称,“陈述的顺序不是评估顺序的标准”。