Haskell - 将 returns 函子应用到函子上

Haskell - applying a function that returns a functor onto a functor

假设我有两个函数 fg,它们都接受常规值和 return 一个 Either 值,如下所示:

g :: a -> Either x b
f :: b -> Either x c

如何将两者链接在一起以获得类似 f . g 的内容?

我想出的最佳解决方案是创建一个名为 applyToRight 的辅助函数,其工作方式如下

applyToRight :: (a -> Either x b) -> Either x a -> Either x b
applyToRight f x =
  case x of
    Left a -> Left a
    Right b -> f b

这样我就可以

applyToRight f (g a)

在这种情况下,我专门讨论 Either,但我认为这个问题可以推广到所有应用函子。处理这个问题最优雅的方法是什么?

不适用。您重新发现了 Monadic 绑定:

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

Either x 是一个 Monad:

> Left "a" >>= (\x -> Right (1+x))
Left "a"

> Right 1 >>= (\x -> Right (1+x))
Right 2

使用 Kleisli 组合运算符(如 f <=< g)链接两个创建 monad 的函数,例如 f <=< g,或者在另一个方向 g >=> f 等价地使用前向组合运算符

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

这个类型更容易理解:

      f ::               b -> Either x c
g       :: a -> Either x b
-----------------------------------------
g >=> f :: a ->               Either x c

事实上,总结单子的一种方法是说它们是关于 广义 函数组合.

>=> 简单定义为

(g >=> f) x  =  g x >>= f 

(f <=< g) x  =  g x >>= f  =  f =<< g x

另请参阅:

  • Monadic types diagram
  • 更多链接

Functor 和 Applicative 都太弱了:Monad 包含您要查找的函数。

applyToRight = flip (>>=)