Мой блог объясняет, что делают reset
и shift
, поэтому вы может захотеть прочитать это еще раз.
Еще один хороший источник, на которую я также указываю в своем блоге, это запись в Википедии о стиле передачи продолжения . Этот, безусловно, самый ясный по предмету, хотя в нем не используется синтаксис Scala и продолжение явно передается.
Документ о разделенных продолжениях, на который я ссылаюсь в своем блоге, но, похоже, стал broken, дает много примеров использования.
Но я думаю, что лучшим примером концепции ограниченных продолжений является Scala Swarm. В нем библиотека останавливает выполнение вашего кода в одной точке, а оставшееся вычисление становится продолжением. Затем библиотека что-то делает - в данном случае передает вычисление другому хосту и возвращает результат (значение переменной, к которой был осуществлен доступ) вычислению, которое было остановлено.
Теперь вы не делаете этого. Я не понимаю даже простого примера на странице Scala, поэтому прочтите мой блог. В нем я только озабочен объяснением этих основ, почему результат 8
.
Продолжение фиксирует состояние вычисления, которое будет вызвано позже.
Подумайте о вычислении между выходом из выражения сдвига и выходом из выражения сброса как функции. Внутри выражения сдвига эта функция называется k, это продолжение. Вы можете передать его, вызвать его позже, даже более одного раза.
Я думаю, что значение, возвращаемое выражением сброса, является значением выражения внутри выражения сдвига после =>, но насчет этого я не совсем конечно.
Таким образом, с продолжениями вы можете заключить довольно произвольный и нелокальный фрагмент кода в функцию. Это может быть использовано для реализации нестандартного потока управления, такого как сопрограммы или обратное отслеживание.
Таким образом, продолжения следует использовать на системном уровне.
Я обнаружил, что существующие объяснения менее эффективны для объяснения концепции, чем я бы надеялся. Надеюсь, это ясно (и правильно). Я еще не использовал продолжения.
Когда вызывается функция продолжения cf
:
блок и начинается снова в конце
cf
, - это то, что блок shift
«оценивает» при продолжении выполнения. это может быть разным для каждого вызова cf
reset
(или до вызова reset
, если блока нет)
сброса
(или параметра сброса
(), если блока нет) - это то, что cf
возвращает cf
до конца блока shift
reset
(или до вызова сброса?) Итак, в этом примере следуйте буквам от A до Z
reset {
// A
shift { cf: (Int=>Int) =>
// B
val eleven = cf(10)
// E
println(eleven)
val oneHundredOne = cf(100)
// H
println(oneHundredOne)
oneHundredOne
}
// C execution continues here with the 10 as the context
// F execution continues here with 100
+ 1
// D 10.+(1) has been executed - 11 is returned from cf which gets assigned to eleven
// G 100.+(1) has been executed and 101 is returned and assigned to oneHundredOne
}
// I
Это напечатает:
11
101