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