によって生成された標準のインタープリターモナドトランスフォーマーの簡略化されたバージョンがありますFreeT
。
data InteractiveF p r a = Interact p (r -> a)
type Interactive p r = FreeT (InteractiveF p r)
p
は「プロンプト」でありr
、「環境」です...次のようなものを使用してこれを実行します:
runInteractive :: Monad m => (p -> m r) -> Interactive p r m a -> m a
runInteractive prompt iact = do
ran <- runFreeT iact
case ran of
Pure x -> return x
Free (Interact p f) -> do
response <- prompt p
runInteractive prompt (f resp)
instance MonadFix m => MonadFix (FreeT (InteractiveF p r)) m a)
mfix = -- ???
このタイプは多かれ少なかれ...の制約されたバージョンにすぎないように感じStateT
ます...どちらかといえば...Interactive p r IO
の制約されたバージョンだIO
と思います...私は思う...しかし...まあ、いずれにせよ、私の直感はそれを言います良い例があるはずです。
書いてみましたが、よくわかりません。これまでの私の最も近い試みは次のとおりです。
mfix f = FreeT (mfix (runFreeT . f . breakdown))
where
breakdown :: FreeF (InteractiveF p r) a (FreeT (InteractiveF p r) m a) -> a
breakdown (Pure x) = x
breakdown (Free (Interact p r)) = -- ...?
MonadFix
のインスタンスを利用したバージョンも試してみましたm
が、うまくいきませんでした -
mfix f = FreeT $ do
rec ran <- runFreeT (f z)
z <- case ran of
Pure x -> return x
Free iact -> -- ...
return -- ...
これが本当に可能かどうか、または不可能な理由を知っている人はいますか? もしそうなら、私が探し続けるのに適した場所はどこですか?
あるいは、私の実際のアプリケーションでは、実際に使用する必要さえありませんFreeT
...使用するだけFree
です。つまり、Interactive
ただのモナド変換子ではなく、ただのモナドであり、
runInteractive :: Monad m => (p -> m r) -> Interactive p r a -> m a
runInteractive _ (Pure x) = return x
runInteractive prompt (Free (Interact p f) = do
response <- prompt p
runInteractive prompt (f response)
一般的な FreeT のケースではなく、このケースで何かが可能であれば、私も嬉しいです:)