假设我有一个计算
class A where
foo :: () -> ()
instance A IO where
foo x = do
print "prefix"
x
print "suffix"
现在,假设我想写
instance A => A (MyMonadTransformerT γ )
然后,在实现foo
时,我被迫“解开”它的论点,例如foo x = lift (foo (unlift x))
. 这个unlift
函数可能不适合单子计算。对于状态转换器,它将被迫忘记程序状态的任何变化。
似乎可以创建一个更通用的方法,该方法也采用提升函数,并导致计算t () -> t ()
,t
提升(转换)单子在哪里。
class Monad => A' where
foo' :: Monad t =>
(forall z . z -> t z) -- lifting function
-> t ()
-> t ()
foo :: () -> ()
foo = foo' id
instance A' IO where
foo' lift x = do
lift (print "prefix")
x
lift (print "suffix")
instance A' => A' (StateT γ ) where
foo' lift' x = foo' (lift' . lift) x
computation :: Num a => StateT a IO ()
computation = do
foo (put 1 >> lift (print "middle"))
v <- get
lift $ print ("value", v)
run_computation :: Num a => IO a
run_computation = execStateT computation 0
问题。这是最好的方法吗?有没有更一般的东西可以写?CPS 风格的代码?谢谢!!