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