私は、さまざまな状況で異なる操作のための2つのフリーモナドを持っています。しかし、1(major
)DSLは、特定の操作は、コンテキストにある場合、別の1(action
)が含まれている必要があります:ハスケルでは、フリーモナドを別のものにどのように埋め込むことができますか?
import Control.Monad.Free
data ActionFunctor next = Wait Timeout next
| Read URI next
instance Functor ActionFunctor where
fmap f (Wait timeout next) = Wait timeout (f next)
fmap f (Read uri next) = Read uri (f next)
type Action = Free ActionFunctor
data MajorFunctor next = Log LogText next
| Act Action next
| Send Message
instance Functor MajorFunctor where
fmap f (Log text next) = Log text (f next)
fmap f (Act action next) = Act action (f next)
fmap f (Send message) = Send message
type Major = Free MajorFunctor
問題があり、GHCは、Act Action next
でAction
が(* -> *)
の一種であることをMajorFunctor
を文句を言うでしょうタイプだけではありません。これは、data ActionFunctor
定義ではタイプパラメータとしてnext
を受け入れる必要があり、Act Action
行にはこのようなパラメータが含まれていないためです。しかし、たとえメッセージは、私は私もMajor
ファンクタで、このような余分の型パラメータを宣言する必要があるかどうかわからないんだけど、私には明らかである:
data MajorFunctor actionNext next = ...
一つだけのデータコンストラクタは、パラメータを使用しますので、それは奇妙に見えますが、しばらくこのような暴露はMajorFunctor
になり、MajorFunctor actionNext
になり、見た目はあまりにも多くの詳細を明らかにします。そこで私はFreeT
変圧器を見て、それが私が望むものかどうかを見ました。しかし、私の場合は、Action
インタプリタに通話する必要があります.DIMプログラムにそのような操作がある場合は、bind
がモナドプログラムに含まれているわけではありません。したがって、変圧器が良い解決策であるかどうかもわかりません。
魔法の解決策!本当にありがとう。 – snowmantw