我想写函数
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