你有
eval (Val n) = Just n
由此我们得出结论,eval产生一个Maybe价值。第二个等式,我们把它改写为
eval (Div x y) =
eval x >>= (\n ->
eval y >>= (\m ->
safediv n m ) )
IE
eval (Div x y) =
eval x >>= g
where
g n = eval y >>= h
where
h m = safediv n m
看?每个应用程序只涉及一个>>=功能。在顶部,它是g. 但是g定义 - 并使用 - h,所以h's 的主体可以访问它的参数 m和g' 的参数,n。
如果eval x产生Nothing,则eval x >>= g根据Nothing类型( ) 的>>=定义立即为,并且不会尝试。MaybeNothing >>= _ = Nothingeval y
但如果是,(Just ...)那么它的值只会被馈送到绑定函数 ( Just x >>= f = f x)。
因此,如果两个evals 都产生Just ...值,则在两个参数和均可访问safediv n m的范围内调用。它可能被定义为nm
safediv :: Num a => a -> a -> Maybe a
safediv n m | m == 0 = Nothing
| otherwise = Just (div n m) -- or something
等等h :: m -> Maybe m和g :: n -> Maybe n适合的类型,
-- assuming a missing type of "expressions", `Exp a`,
eval :: Num a => Exp a -> Maybe a
-- Num a is assumed throughout, below
eval (Div x y) = -- Maybe a
-- Maybe a >>= a -> Maybe a
eval x >>= g
where
-- a -> Maybe a
-- Maybe a >>= a -> Maybe a
g n = eval y >>= h
where
-- a -> Maybe a
h m = safediv n m -- Maybe a
-- safediv :: a -> a -> Maybe a
根据 Maybe monad 的绑定类型,
(>>=) :: Maybe a ->
(a -> Maybe b) ->
Maybe b