我得到的问题是这样说的:
类型 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 定律。