私は質問を拡大するためにあまりできません。しかし、ここで使用する場合は、次のとおりです。あなたが同じモナドm
上で変換、2つのモナド変圧器、t
とs
を持っているとしましょう:彼らは互いに通信することができますslave
よう2つのモナド変圧器が異なるタイプのものであっても、それらの基礎となるモナドが同じタイプのものであれば、原理的な方法がありますか?
master :: (MonadTrans t, Monad m) => t m a b
slave :: (MonadTrans t, Monad m) => s m a b
そして、私はmaster
を構成したいとするときm
プリミティブはt
とs
に持ち上げられます。署名は、かもしれない:
bound :: (MonadTrans t, MonadTrans s, Monad m, Monoid a) => t m a b -> s m a b -> (...)
But what is the type of (...) ?
ユースケース、シュガー入りの表記:
master :: Monoid a => a -> t m a b
master a = do
a <- lift . send $ (a,False) -- * here master is passing function param to slave
... -- * do some logic with a
b <- lift . send $ (mempty,True) -- * master terminates slave, and get back result
slave :: Monoid a => (a -> b) -> s m a b
slave g = do
(a,end) <- lift receive
case end of
True -> get >>= \b -> exit b
_ -> (modify (++[g a])) >> slave g
更新:send
とreceive
タイプm
のプリミティブです。
この例題が工夫されていたり、コルーチンに似ていたりすると、質問の精神と実際には関係がないので、すべての類似点を無視してください。しかし、主なポイントは、モナドt
とs
は以前はお互いに分かりやすく構成することができませんでしたが、どちらも基礎モナドをラップした後、それらを合成して単一の関数として実行できるようになりました。合成された関数の型については、私は実際にはいくつかの方向が評価されているか分からない。今、この抽象化がすでに存在していて、それについてはわかりません。
's'と' t'は任意であるか、何らかの形で具体的です - このような 's'と' t'を作成しようとしていますか?そして同じ質問が 'm'にも当てはまります - それについて、' send'と 'receive'についてどうですか? –
はい 's'と' t'は任意です。 'm'はここで作成しようとしている特定のタイプです。 'send'と' receive'は '(a、Bool) - > m a b'と' m a b'型の単なる基本関数です。しかし、彼らは私が与えた考案されたユースケースに付随しているので、その実装の詳細は重要ではありません。 – chibro2