你有
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
类型( ) 的>>=
定义立即为,并且不会尝试。Maybe
Nothing >>= _ = Nothing
eval y
但如果是,(Just ...)
那么它的值只会被馈送到绑定函数 ( Just x >>= f = f x
)。
因此,如果两个eval
s 都产生Just ...
值,则在两个参数和均可访问safediv n m
的范围内调用。它可能被定义为n
m
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