Я действительно очень борюсь с пониманием callCC. Я получаю силу от Continuations и использую концепцию в некоторых своих проектах для создания классных концепций. Но мне никогда не приходилось использовать что-то с большими возможностями, чем cont :: ((a->r)->r)-> Cont r a
.
После его использования становится понятным, почему они называют Cont Monad матерью всех монад, ДА, я не понимаю, когда мне нужно будет использовать callCC
, и это точно мой вопрос.
haskell
functional-programming
monads
Алехандро Навас
источник
источник
Cont
? Когда вы говорите, что вам не нужно использовать что-то более мощноеcont
, значит ли это, что вы не использовалиreset
илиshift
то и другое?reset
илиshift
. Я использовал его, чтобы определить внедренный язык, который можно приостановить до тех пор, пока данное действие не будет разрешено другим процессом, а затем он возобновится с заданным «продолжением». Может быть, у меня сложилось впечатление, что у меня большой опыт работы с Cont Monad, но на самом деле не так много, я просто очень хочу понять callCCОтветы:
callCC
дает вам семантику «раннего возврата», но в монадическом контексте.Скажем , вы хотите
doOne
, и если это возвращаетсяTrue
, вы немедленно прекратить, в противном случае вы идете кdoTwo
иdoThree
:Видишь это
if
ветвление там? Одна ветвь не так уж и плоха, с ней можно иметь дело, но представьте, что есть несколько таких точек, где вы просто хотите получить залог? Это очень уродливо очень быстро.С ним
callCC
вы можете получить «ранний возврат»: вы делаете залог в точке ветвления и не должны вкладывать оставшиеся вычисления:Гораздо приятнее читать!
Что еще более важно, поскольку
ret
здесь не специальный синтаксис (какreturn
в C-подобных языках), а просто значение, как у любого другого, вы можете передать его и другим функциям! И эти функции могут затем выполнять то, что называется «нелокальным возвратом» - то есть они могут «останавливать»doThings
вычисления, даже от нескольких вложенных вызовов вглубь. Например, я мог бы выделить проверкуdoOne
результата в отдельную функцию,checkOne
подобную этой:источник
b
в основном это просто подстановочный знак, так что вы можете связать больше продолжений внутри callCC. В любом случае, послеret
применения продолжение, созданное вызовом cc, «вернет» все, что было вставленоret
. Это довольно замысловато, но довольно умно, но чрезвычайно мощно. Я не вижу много мест, где использование такой силы не похоже на убийство мухи с помощью