タイプ (a -> mb) の 2 つの関数を追加して、両方の結果を追加する同じタイプの関数を 1 つだけ取得する場合は、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 ではよくあることですが、正当な理由があるのではないかと疑っていますが、どれかを見つけることができません。
ノート
この質問は、この質問にかなり似ています。ただし、モノイドでは、次のようなインスタンスを定義する方法がわかりません。
instance (Monad m, Monoid b) => Monoid (a -> m b) where
[...]
すでにインスタンスがあるため:
instance Monoid b => Monoid (a -> b) where
[...]