Что такое продолжения Scala и почему используют их?

Нет, общедоступное наследование только.

84
задан Community 23 May 2017 в 11:54
поделиться

3 ответа

Мой блог объясняет, что делают reset и shift , поэтому вы может захотеть прочитать это еще раз.

Еще один хороший источник, на которую я также указываю в своем блоге, это запись в Википедии о стиле передачи продолжения . Этот, безусловно, самый ясный по предмету, хотя в нем не используется синтаксис Scala и продолжение явно передается.

Документ о разделенных продолжениях, на который я ссылаюсь в своем блоге, но, похоже, стал broken, дает много примеров использования.

Но я думаю, что лучшим примером концепции ограниченных продолжений является Scala Swarm. В нем библиотека останавливает выполнение вашего кода в одной точке, а оставшееся вычисление становится продолжением. Затем библиотека что-то делает - в данном случае передает вычисление другому хосту и возвращает результат (значение переменной, к которой был осуществлен доступ) вычислению, которое было остановлено.

Теперь вы не делаете этого. Я не понимаю даже простого примера на странице Scala, поэтому прочтите мой блог. В нем я только озабочен объяснением этих основ, почему результат 8 .

37
ответ дан 24 November 2019 в 08:39
поделиться

Продолжение фиксирует состояние вычисления, которое будет вызвано позже.

Подумайте о вычислении между выходом из выражения сдвига и выходом из выражения сброса как функции. Внутри выражения сдвига эта функция называется k, это продолжение. Вы можете передать его, вызвать его позже, даже более одного раза.

Я думаю, что значение, возвращаемое выражением сброса, является значением выражения внутри выражения сдвига после =>, но насчет этого я не совсем конечно.

Таким образом, с продолжениями вы можете заключить довольно произвольный и нелокальный фрагмент кода в функцию. Это может быть использовано для реализации нестандартного потока управления, такого как сопрограммы или обратное отслеживание.

Таким образом, продолжения следует использовать на системном уровне.

8
ответ дан 24 November 2019 в 08:39
поделиться

Я обнаружил, что существующие объяснения менее эффективны для объяснения концепции, чем я бы надеялся. Надеюсь, это ясно (и правильно). Я еще не использовал продолжения.

Когда вызывается функция продолжения cf :

  1. Выполнение пропускает оставшуюся часть сдвига блок и начинается снова в конце
    • параметр, переданный в cf , - это то, что блок shift «оценивает» при продолжении выполнения. это может быть разным для каждого вызова cf
  2. Выполнение продолжается до конца блока reset (или до вызова reset , если блока нет)
    • результат блока сброса (или параметра сброса (), если блока нет) - это то, что cf возвращает
  3. Выполнение продолжается после cf до конца блока shift
  4. Выполнение пропускается до конца блока 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
31
ответ дан 24 November 2019 в 08:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: