我正在學習monad變壓器,我很困惑什麼時候使用電梯是必要的。 假設我有以下代碼(它沒有做任何有趣的事情,只是我可以用來演示的最簡單的東西)。當monad變壓器需要提升嗎?
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
。
現在,在第三個when
做遞歸阻塞程序需要一個電梯編譯。在第二個街區,沒有電梯需要,但我不知何故假設這是因爲存在exit
,它以某種方式迫使線上線提升到ContT
。但在第一個街區,不需要電梯。 (但是,如果明確添加,也沒有問題。)這真讓我感到困惑。我覺得所有的塊都是等效的,無論是在任何地方或任何地方都需要電梯。但這顯然不是真的。需要/不需要升降梯的關鍵區別在哪裏?