モナド・トランスを学んでいますが、リフトを使う必要があるときは混乱しています。 次のコードがあるとします(これは面白いことではありません。デモンストレーションでは最も簡単なコードです)。モナド・トランスでリフティングが必要なのはいつですか?
foo :: Int -> State Int Int
foo x = do
(`runContT` pure) $ do
callCC $ \exit -> do
when (odd x) $ do
-- lift unnecessary
a <- get
put $ 2*a
when (x >= 5) $ do
-- lift unnecessary, but there is exit
a <- get
exit a
when (x < 0) $ do
-- lift necessary
a <- lift $ foo (x + 10)
lift $ put a
lift get
だから、メインDOブロックがContT Int (StateT Int Identity) Int
を入力したモナドスタックは、そこにあります。
ここで、第3のwhen
は再帰でブロックします。プログラムをコンパイルするにはリフトが必要です。 2番目のブロックでは、揚力は必要ありませんが、どういうわけか、線の上にある線をContT
にするように、exit
の存在が原因であると思います。しかし、最初のブロックでは、持ち上げる必要はありません。 (ただし明示的に追加しても問題ありません)これは本当に私にとって混乱しています。私はすべてのwhen
ブロックが同等であると感じて、リフトはどこにでもどこにも必要であるはずです。しかし、それは明らかに真実ではありません。エレベーターの必要/不要の主な違いはどこですか?