让我们看一下Maybe
monad的定义。
instance Monad Maybe where
return = Just
Just a >>= f = f a
Nothing >>= _ = Nothing
并do
在您的函数中对 -notation 进行脱糖:
func' =
Nothing >>= \a ->
return a
>>=
is的第一个参数Nothing
,从上面的定义我们可以看到它>>=
忽略了第二个参数。所以我们得到:
func' = Nothing
由于该函数\a -> ...
永远不会被调用,因此a
永远不会被分配。所以答案是:a
甚至没有达到。
至于去糖do
符号,这里是它如何完成的一个快速草图(我做了一个简化 - 处理fail
,即不匹配的模式):
do {a; rest} → a >> do rest
请注意,>>
通常以>>=
as的形式实现a >>= \_ -> do rest
(即第二个函数只是忽略参数)。
do {p <- a; rest} → a >>= \p -> do rest
do {let x = a; rest} → let x = a in do rest
最后:
do {a} = a
这是一个例子:
main = do
name <- getLine
let msg = "Hello " ++ name
putStrLn msg
putStrLn "Good bye!"
脱糖:
main =
getLine >>= \name ->
let msg = "Hello " ++ name in
putStrLn msg >>
putStrLn "Good bye!"
为了让那些好奇的人更完整,这里是do {p <- a; rest}
(直接取自 Haskell 报告)的“正确”翻译:
do {pattern <- a; rest} → let ok pattern = do rest
ok _ = fail "error message"
in a >>= ok