GHC手册说明了GHCI中的一元结合:
两种类型的绑定之间的另一个重要区别是monadic绑定(p < - e)是严格的(它评估e),而使用let形式,表达式不会立即评估:
(从这里)
但我可以在GHCI中做到这一点:
?: x <- return $ error ":("
?: :sprint x
x = _
Run Code Online (Sandbox Code Playgroud)
这似乎表明monadic绑定并不严格.我错过了什么?
请记住,严格的功能意味着f ⊥ = ⊥.考虑:
ghci> x <- return undefined
-- no error
Run Code Online (Sandbox Code Playgroud)
这意味着,return undefined >>= \x -> ...不⊥,但这并不能说有关的严格什么>>=原因的,return.然而,这:
ghci> y <- undefined
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)
是手册所指的情况,它表明左边的参数绑定是严格的,因为undefined >>= (\y -> ...)是⊥.最后,
ghci> :set -XBangPatterns
ghci> !z <- return undefined
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)
这一行显示了如果我们给它一个严格的函数作为参数会发生什么,所以我们知道return undefined >>= f⊥ 如果f是严格的话.这实际上遵循了monad法则return x >>= f = f x,所以return ⊥ >>= f = f ⊥ = ⊥
在Haskell中,我们将值与计算执行的评估分开.return (error "")是一个成功返回未定义值的计算,绑定时不计算该值.error "" :: IO a是一个未定义的计算,立即失败.