Не понимайте набора кондиционированных продолжений Скалы (@cpsparam [b, c])

StackOverflow https://stackoverflow.com/questions/2437676

Вопрос

Я изо всех сил пытаюсь понять, что именно это делает A @cpsParam[B,C] И какие типы этой формы я должен назначить своим значениям при использовании объекта по разграниченным продолжениям.

Я посмотрел на некоторые источники:

http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf

http://www.scala-lang.org/node/2096

http://dcsobral.blogspot.com/2009/07/delimited-continuations-explaiden-in.html

http://blog.richdougherty.com/2009/02/delimited-continuations-in-scala_24.html

Но они не дали мне особой интуиции в это. В последней ссылке автор пытается дать явное объяснение, но в любом случае это не достаточно ясно.

A здесь представляет выход вычисления, который также является входом в его продолжение. B представляет собой тип возврата этого продолжения, а C представляет его «окончательный» тип возврата - потому что сдвиг может сделать дальнейшую обработку до возвращаемого значения и изменить его тип.

Я не понимаю разницы между «выходом вычислений», «Возвратом типа продолжения» и «Окончательным типом возврата продолжения». Они звучат как синонимы.

Это было полезно?

Решение

Итак, люди помогли мне с этим в другом месте. Вот ответ:

reset ({
    ...
    ...shift((k:A=>B) => ...::C)::A...
    ...
}::B)::C

Так, shift яма типа A в вычислении {...} типа B. Анкет Аргумент shift Возвращает значение типа C и поэтому reset ({...}) имеет тип C.

Ключевым трюком в понимании этого материала было увидеть, что {...} а также reset {...} иметь другой тип в зависимости от того, какой тип shiftАргумент возвращается.

Например:

reset ({
    "number "+shift((k:Int=>String) => List(k(1), k(2), k(3)))
})

возврат List("number 1", "number 2", "number 3").

Здесь A является Int, B является String, C является List[String] потому что {"number" + _} (здесь) функция из Int к String и аргумент shift, учитывая эту функцию, создает List[String], который становится результатом reset({...}).

Другие советы

Я все еще нахожусь в процессе выяснения точных правил/последствий для печати, связанных здесь.

Кажется легким/простым, если типы в примерах «достаточно просты», чтобы «хорошо соответствовать», как показано выше, но он становится более междоулистым/трудным (по крайней мере для меня) в сравнении с вещами с типированием, давая Tiark Rompf:

|- e: A@cpsParam[B,C]; {[|r|]}: U
-----------------------------------------------------
[|val x: A = e; r|] = [|e|].map( (x: A) => {[|r|]} )

так что результат [|e|].map( (x: A) => {[|r|]} ) будет иметь тип Shift[U,B,C] Согласно определению карты, приведенной в статье Тиарка.

Здесь ты не обязательно такой же, как Б.

До сих пор я не понимаю, почему тебе разрешено отличаться от б без чего -либо вродеU <: B дано в определении карты в статье Тиарка.

Что мне не хватает повторения, чтобы понять здесь?

Есть советы/идеи?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top