関数を書きたい
fixProxy :: (Monad m, Proxy p) => (b -> m b) -> b -> () -> p a' a () b m r
fixProxy f a () = runIdentityP $ do
v <- respond a
a' <- lift (f a)
fixProxy f a' v
プロキシを実行しようとするまでは、あなたが思うように動作します
>>> :t \g -> runRVarT . runWriterT . runProxy $ fixProxy g 0 >-> toListD
(Num a, RandomSource m s, MonadRandom (WriterT [a] (RVarT n)),
Data.Random.Lift.Lift n m) =>
(a -> WriterT [a] (RVarT n) a) -> s -> m (a, [a])
でのクラスRVarT
の存在を強調するために意図的に使用しています。私が探しているもの、次のような関数をカプセル化する必要がある自然な変換の存在を表します。Lift
RVar
Lift
n :~> m
fixProxy :: (Monad m, Monad n, Lift m n, Proxy p)
=> (b -> m b) -> b -> () -> p a' a () b n r
正しいLift
答え (多くの孤立したインスタンスが必要になる) ですか、それともより標準的な自然変換 MPTC を使用する必要がありますか?
以下のコメントで説明されているように、実用的な解決策は次のようなものであることに注意してください
runRVarT . runWriterT . runProxy
$ hoistK lift (fixProxy (const $ sample StdUniform) 0) >-> toListD