Domanda

sto lottando per capire cosa esattamente vuol dire quando un valore è di tipo A @cpsParam[B,C] e quali tipi di questa forma dovrei assegnare ai miei valori quando si utilizza l'impianto continuazioni delimitato.

Ho guardato alcune fonti:

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

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

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

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

, ma non mi hanno dato molta intuizione in questo. Nel l'ultimo anello, l'autore cerca di dare una spiegazione esplicita, ma non è abbastanza chiaro in ogni caso.

  

L'A qui rappresenta l'uscita del calcolo, che è anche l'ingresso alla sua continuazione. Il B rappresenta il tipo di ritorno che il mantenimento e il C rappresenta il suo ritorno tipo perché "finale" shift può fare ulteriore trattamento al valore restituito e cambiare il tipo.

Non capisco la differenza tra "uscita del calcolo", "tipo di ritorno della continuazione" e "tipo ritorno finale della continuazione". Suonano come sinonimi.

È stato utile?

Soluzione

Così, la gente mi ha aiutato con questo altrove. Ecco la risposta:

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

Quindi, shift è un foro di tipo A in una {...} calcolo di tipo B. L'argomento di shift restituisce un valore di tipo C ed è per questo reset ({...}) ha tipo C.

Il trucco chiave nella comprensione di questo roba era di vedere che {...} e reset {...} hanno diverso tipo a seconda del tipo ritorna l'argomento del shift.

Ad esempio:

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

ritorna List("number 1", "number 2", "number 3").

Qui A è Int, B è String, C è List[String] perché {"number" + _} è (qui) una funzione da Int al String e l'argomento di shift, in tale funzione, produce una List[String], che diventa risultato della reset({...}).

Altri suggerimenti

Sono ancora in un processo di capire l'esatta battitura regole / implicazioni coinvolte nel qui.

Sembra facile / più facile se i tipi negli esempi sono "abbastanza semplice" a "adattarsi bene", come indicato sopra, ma diventa più interresting / difficile (almeno per me) nel confronto tra le cose al di battitura dare da tiark Rompf:

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

in modo che il risultato di [|e|].map( (x: A) => {[|r|]} ) avrà il tipo Shift[U,B,C] secondo la definizione di carta dato in carta di tiark.

Qui U non è necessariamente essere uguale a B.

Finora non capisco il motivo per cui U è consentito di essere diverso da B senza qualcosa di simile U <: B data nella definizione di carta in carta di tiark.

Che cosa mi manca repsectively non riuscendo a capire qui?

Qualche consiglio / idee?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top