如果您希望附加两个 (a -> mb) 类型的函数,以便只获得一个附加两个结果的相同类型的函数,则可以使用 Kleisli 来执行此操作:
instance (Monad m, Monoid b) => Monoid (Kleisli m a b) where
mempty = Kleisli (\_ -> return mempty)
mappend k1 k2 =
Kleisli g
where
g x = do
r1 <- runKleisli k1 x
r2 <- runKleisli k2 x
return (r1 <> r2)
但是,目前没有在 中定义这样的实例Control.Arrow
。通常,在 Haskell 中,我怀疑有一个很好的理由,但找不到哪一个。
笔记
这个问题与这个问题很相似。但是,对于 Monoid,我看不到定义实例的方法,例如:
instance (Monad m, Monoid b) => Monoid (a -> m b) where
[...]
因为已经有一个实例:
instance Monoid b => Monoid (a -> b) where
[...]