我目前正在努力解决 Haskell 的一个新元素:Monads。因此,通过创建一个 (>>=)
运算符的示例向我介绍了这一点,该运算符在 Maybe
类型上执行函数(将其实际整数值作为其参数) ) 仅当它不等于 Nothing
时才返回,否则返回 Nothing
:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing
(Just x) >>= f = f x
但是,我不太确定它的以下用法是如何工作的:
eval (Val n) = Just n
eval (Div x y) = eval x >>= (\n ->
eval y >>= (\m ->
safediv n m))
在我看来, (>>=)
运算符只需要一个 Maybe
值和一个返回 1 的函数,但是在这个示例使用代码中,它看起来像它需要两次 Maybe
值和一次函数。然而,我被告知它评估x
,将结果放入n
,然后评估y
,将结果放入y
code>,然后在两者上执行 safediv
函数。虽然我不明白 (>>=)
运算符在这里如何发挥作用;这是如何运作的?
最佳答案
你可以这样阅读:
eval (Div x y) = eval x >>= (\n ->
eval y >>= (\m ->
safediv n m))
当你想要eval (Div x y)
然后
- 第一个
评估x
: - 如果是
Just n
(使用第一个>>=)
- 如果是
- 然后使用
n
并查看eval y
(使用第一个>>=)
- 然后使用
- 如果最后一个是
Just m
(第二个>>=)
- 如果最后一个是
- 然后选择
m
并执行(第二个>>=)
- 然后选择
savediv n m
返回结果 - 您仍然拥有闭包中的n
!
在其他情况下返回Nothing
所以这里的(>>=)
只是帮助你解构。
也许采用 do
形式更容易阅读和理解:
eval (Val n) = Just n
eval (Div x y) = do
n <- eval x
m <- eval y
safediv n m
这只是 (>>=)
周围的语法糖
让我们追查案件:
1.eval x = Nothing
和 eval y = Nothing
:
eval x >>= (...) = Nothing >>= (...) = Nothing
2. eval x = Nothing
和 eval y = Just n
:
这是一样的:
eval x >>= (...) = Nothing >>= (...) = Nothing
3. eval x = Just n
和 eval y = Nothing
:
eval x >>= (\n -> eval y >>= (...))
= Just n >>= (\n -> eval y >>= (...))
= Just n >>= (\n -> Nothing)
= Nothing
4. eval x = Just n
和 eval y = Just m
:
eval x >>= (\n -> Just m >>= (...))
= Just n >>= (\n -> Just m >>= (...))
= Just n >>= (\n -> Just m >>= (\m -> safediv n m))
= (first >>= for Just) = Just m >>= (\n -> safediv n m)
= (second >>= for Just) = safediv n m
关于haskell - 也许是 monad 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26240534/