我目前正在为Haskell的一个新元素而奋斗:Monad。因此,我是通过创建一个(>>=)操作符来介绍这个问题的,该操作符仅在不等于Nothing的情况下执行Maybe类型上的函数(以其实际整数值作为参数),否则返回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值和一个返回一个Maybe值的函数,但是在这个例子中,使用代码似乎需要2倍的Maybe值和一次函数。然而,我被告知,它计算x,将结果放入n,然后计算y,将结果放在y中,然后在这两个方面执行safediv函数。虽然我看不出(>>=)操作符是如何在这里发挥作用的;这是如何工作的呢?
发布于 2014-10-07 16:17:14
你可以这样读:
eval (Div x y) = eval x >>= (\n ->
eval y >>= (\m ->
safediv n m))当你想做eval (Div x y)的时候
eval xJust n (使用第一个>>=)
n并查看eval y (使用第一个>>=)。
Just m (第二个>>=)
m并做一个(第二个>>=)
savediv n m返回它的结果-您仍然拥有关闭的n!
在任何其他caes中返回Nothing
所以在这里,(>>=)只会帮助你解构。
也许在do表单中更容易阅读和理解:
eval (Val n) = Just n
eval (Div x y) = do
n <- eval x
m <- eval y
safediv n m它只是(>>=)周围的语法糖
我们来查案吧:
eval x = Nothing和eval y = Nothing:eval x >>= (...) = Nothing >>= (...) = Nothingeval x = Nothing和eval y = Just n:这也是一样的:
eval x >>= (...) = Nothing >>= (...) = Nothingeval x = Just n和eval y = Nothing:eval x >>= (\n -> eval y >>= (...))
= Just n >>= (\n -> eval y >>= (...))
= Just n >>= (\n -> Nothing)
= Nothingeval 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发布于 2014-10-07 16:36:44
让我们进行元素追逐来说明它是如何工作的。如果我们有
eval (Div (Val 5) (Div (Val 0) (Val 1)))然后我们就可以把它分解成
eval (Div (Val 5) (Div (Val 0) (Val 1)))
= eval (Val 5) >>=
(\n ->
eval (Div (Val 0) (Val 1)) >>=
(\m ->
safediv n m
)
)
-- eval (Val 5) = Just 5
= Just 5 >>=
(\n ->
eval (Div (Val 0) (Val 1)) >>=
(\m ->
safediv n m
)
)
-- Just x >>= f = f x
= (\n ->
eval (Div (Val 0) (Val 1)) >>=
(\m ->
safediv n m
)
) 5
-- Substitute n = 5, since the 5 is the argument to the `\n ->` lamba
= eval (Div (Val 0) (Val 1)) >>=
(\m ->
safediv 5 m
)现在我们需要绕道计算eval (Div (Val 0) (Val 1)).
eval (Div (Val 0) (Val 1))
= eval (Val 0) >>=
(\n ->
eval (Val 1) >>=
(\m ->
safediv n m
)
)
-- eval (Val 0) = Just 0
-- eval (Val 1) = Just 1
eval (Div (Val 0) (Val 1))
= Just 0 >>=
(\n ->
Just 1 >>=
(\m ->
safediv n m
)
)
-- Just x >>= f = f x
eval (Div (Val 0) (Val 1))
= (\n ->
(\m ->
safediv n m
) 1
) 0
= (\n -> safediv n 1) 0
= safediv 0 1
= Just 0现在回到我们对eval的原始调用,在以下内容中替换Just 0:
eval (Div (Val 5) (Div (Val 0) (Val 1)))
= Just 0 >>= (\m -> safediv 5 m)
-- Just x >>= f = f x
eval (Div (Val 5) (Div (Val 0) (Val 1)))
= safediv 5 0
-- safediv x 0 = Nothing
eval (Div (Val 5) (Div (Val 0) (Val 1)))
= Nothinghttps://stackoverflow.com/questions/26240534
复制相似问题