Если вы хотите добавить две функции типа (a → m b), чтобы вы получили только одну функцию того же типа, добавляющую оба результата, вы можете использовать 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
[...]