callCC 「アーリーリターン」のセマンティクスを提供しますが、モナディックコンテキストです。
あなたがしたいと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そこに分岐?1つの分岐はそれほど悪くなく、対処できますが、保釈したい場所が複数あると想像してみてください。これはすぐに醜くなります。
ではcallCC、あなたは「早期復帰」を持つことができます:あなたは、分岐点での救済と巣に計算の残りの部分を持っていません。
doThings = callCC \ret -> do
one <- doOne
when one $ ret ()
doTwo
doThree
読む方がずっと楽しい!
さらに重要なことは、retここは(returnCのような言語のような)特別な構文ではなく、他のような単なる値なので、他の関数に渡すこともできます!そして、これらの関数は、いわゆる「非ローカルリターン」を実行できます。つまり、doThingsネストされた複数の呼び出しの深さからでも、計算を「停止」できます。たとえば、doOneの結果のチェックを次のcheckOneような別の関数に分解できます。
checkOne ret = do
one <- doOne
when one $ ret ()
doThings = callCC \ret -> do
checkOne ret
doTwo
doThree
Contか?より強力なものを使用する必要がないと言った場合cont、それは使用していないということですか、resetそれともshiftどちらかですか?