フリーライブラリのFreeT型を使用して、基になる を「実行」するこの関数を記述しています。StateT
runStateFree
:: (Functor f, Monad m)
=> s
-> FreeT f (StateT s m) a
-> FreeT f m (a, s)
runStateFree s0 (FreeT x) = FreeT $ do
flip fmap (runStateT x s0) $ \(r, s1) -> case r of
Pure y -> Pure (y, s1)
Free z -> Free (runStateFree s1 <$> z)
ただし、代わりに、教会でエンコードされたバージョンであるFTで動作するように変換しようとしています。
runStateF
:: (Functor f, Monad m)
=> s
-> FT f (StateT s m) a
-> FT f m (a, s)
runStateF s0 (FT x) = FT $ \ka kf -> ...
しかし、私はまったく同じ運を持っていません。私が得たあらゆる種類の組み合わせは、うまくいかないようです。私が得た最も近いのは
runStateF s0 (FT x) = FT $ \ka kf ->
ka =<< runStateT (x pure (\n -> _ . kf (_ . n)) s0
しかし、最初の穴m r -> StateT s m rの型は であり、2 番目の穴の型はStateT s m r -> m r...つまり、その過程で状態を失うことになります。
FreeTすべての関数が で記述できることを知っていFTます。ラウンドトリップを伴わないFreeT(つまり、 と を明示的に一致させる必要がある方法でPure)これを記述する良い方法はありFreeますか? s(手動でインライン化を試みましたが、 の定義で異なる を使用して再帰を処理する方法がわかりませんrunStateFree)。それとも、これは、明示的な再帰データ型が教会 (mu) エンコーディングよりも必然的にパフォーマンスが高いケースの 1 つですか?