我真的很难理解 callCC。我得到了延续的力量,我一直在我的一些项目中使用这个概念来创造很酷的概念。但是我从来不需要使用比 cont :: ((a->r)->r)-> Cont r a
更强大的东西。 .
使用它之后,为什么他们称 Cont Monad 为所有 monads 之母是很有意义的,然而,我不知道什么时候需要使用 callCC
,这正是我的问题。
最佳答案
callCC
为您提供“提前返回”语义,但在单子(monad)上下文中。
说你想doOne
,如果返回 True
, 立即停止,否则继续 doTwo
和 doThree
:
doOne :: Cont r Bool
doTwo :: Cont r ()
doThree :: Cont r ()
doThings :: Cont r ()
doThings = do
one <- doOne
if one
then pure ()
else do
doTwo
doThree
看到
if
在那里分支?一个分支还不错,可以处理,但想象一下有多个这样的点你只想保释?这很快就会变得非常难看。与
callCC
您可以“提前返回”:您可以在分支点保释,而不必嵌套其余的计算:doThings = callCC \ret -> do
one <- doOne
when one $ ret ()
doTwo
doThree
读起来更愉快!
更重要的是,由于
ret
这不是一个特殊的语法(如 return
在类 C 语言中),而只是一个与其他值一样的值,您也可以将其传递给其他函数!然后这些函数可以执行所谓的“非本地返回” - 即它们可以“停止” doThings
计算,甚至来自多个嵌套调用。例如,我可以排除对 doOne
的检查。的结果到一个单独的函数 checkOne
像这样:checkOne ret = do
one <- doOne
when one $ ret ()
doThings = callCC \ret -> do
checkOne ret
doTwo
doThree
关于haskell - 我可以用 callCC 做什么而不能用 cont 完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58733711/