Haskell 继续单子向前跳
在程序中可以使用延续单子向后跳转:Haskell 继续单子向前跳,haskell,functional-programming,monads,continuations,monad-transformers,Haskell,Functional Programming,Monads,Continuations,Monad Transformers,在程序中可以使用延续单子向后跳转: {-# LANGUAGE RecursiveDo #-} import Control.Monad.Fix import Control.Monad.Trans.Cont setjmp = callCC (\c -> return (fix c)) backward = do l <- setjmp -- some code to be repeated forever l {-#语言递归DO} 导入控制.Monad.Fix 进
{-# LANGUAGE RecursiveDo #-}
import Control.Monad.Fix
import Control.Monad.Trans.Cont
setjmp = callCC (\c -> return (fix c))
backward = do
l <- setjmp
-- some code to be repeated forever
l
{-#语言递归DO}
导入控制.Monad.Fix
进口管制.单子.交易.续
setjmp=callCC(\c->return(fixc))
向后=做
l如果您将死代码移动到callCC
中,您可以这样做:
import Control.Monad.Cont
forward :: ContT () IO ()
forward = do
callCC $ \skip -> do
skip ()
lift $ putStrLn "This is not executed"
lift $ putStrLn "Control flow continues here"
main :: IO ()
main = runContT forward return
不可能完全按照你的意愿去做。想知道为什么,考虑这个例子:
mdo
l
c <- lift getChar
l <- if c == 'a' then setjmp else return (return ())
lift $ putStrLn "end"
在这里,我们将我们跳过的部分(l1
)的延续传递回外部代码,以便它可以跳转到那里 感谢您尝试回答,但这里的重点不是有死代码(足够简单),而是能够在某些代码中向前跳转。这怎么不向前跳转呢?它跳转到lift$putStrLn“这是未执行的”
,这在代码中更进一步?@Bob更新了问题答案,以包含一个示例,说明为什么在您的答案中不可能出现这种情况,以后无法在跳过的代码中跳回。所以这真的是死代码。我想要像转到L2:L1:一些代码;转到终点;L2:转到L1;结束:return()
您能否为您的答案配备帮助功能,如setjmp
,以使前向跳转看起来不那么尴尬,并可能与后向跳转一样可爱?我不确定是否有可能比@bennofs的建议做得更好(尽管您可能会定义一些帮助功能以使其不那么尴尬),什么应该mdo l;x@ØrjanJohansen:说得好!(1) 它应该做什么:应该暂停执行,直到x
的值为print
准备就绪(在您的示例中,它从未准备就绪,因此永远暂停)。(2) 我该如何实现它:这应该是由懒惰造成的。有没有更完整的例子来说明你想要实现什么?你可以带着论点跳回去,也许这就足够完成你的任务了?@JohnL:我只是想理解延续。我读到continuations足以在函数式语言中实现goto。但我不知道如何在哈斯克尔跳下去。请写一个关于“带着争论跳跃”的答案。也许你是在问关于Monad Goto
。试试这个:
mdo
l
c <- lift getChar
l <- if c == 'a' then setjmp else return (return ())
lift $ putStrLn "end"
import Control.Monad.Cont
forward :: ContT () IO ()
forward = do
callCC $ \end -> do
l1 <- callCC $ \l2 -> do
callCC $ \l1 -> l2 l1
liftIO $ putStrLn "In L1"
end ()
liftIO $ putStrLn "In L2"
l1 ()
liftIO $ putStrLn "End"
main :: IO ()
main = runContT forward return