計算があるとしましょう
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 スタイルのコード? ありがとう!!