我得到的问题是这样说的:



类型 Maybe a 和函数 mapMaybe 是这样编码的:

data Maybe a = Nothing | Just a

mapMaybe g Nothing = Nothing
mapMaybe g (Just x) = Just (g x)

我尝试使用这样的组合:
composeMaybe f g = f.g

但它不编译。

有人能指出我正确的方向吗?

最佳答案

您正在寻找的工具已经存在。 Control.Monad 中有两个 Kleisli 组合运算符。

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

当 m = Maybe 时,composeMaybe 的实现就很明显了:
composeMaybe = (>=>)

查看 (>=>) 的定义,
f >=> g     = \x -> f x >>= g

如果你想用你自己的方式来考虑它,你可以内联
composeMaybe f g x = f x >>= g

或者可以用 do -sugar 写成:
composeMaybe f g x = do
    y <- f x
    g y

一般来说,我只会坚持使用 (>=>) ,它有很好的存在理论理由,因为它提供了最清晰的方式来陈述 monad 定律。

10-08 13:07