Ocaml Fortsetzung vorbei Stil
-
28-09-2019 - |
Frage
Ich bin neu in ocaml und tryin eine Fortsetzung vorbei Style-Funktion zu schreiben, aber ganz verwirrt, welchen Wert ich in zusätzliches Argument übergeben müssen auf k
zum Beispiel, kann ich eine rekursive Funktion schreiben, die true zurückgibt, wenn alle Elemente der Liste selbst ist, sonst false.
so sein wie
let rec even list = ....
auf CPS, ich weiß, ich brauche ein Argument hinzufügen Funktion zu übergeben so wie
let rec evenk list k = ....
aber ich habe keine Ahnung, wie man mit dieser k umgehen und wie funktioniert das genau Arbeit
zum Beispiel für diese Funktion auch, Umgebung sieht aus wie
val evenk : int list -> (bool -> ’a) -> ’a = <fun>
evenk [4; 2; 12; 5; 6] (fun x -> x) (* output should give false *)
Lösung
Die Fortsetzung k
ist eine Funktion, die das Ergebnis von evenk
und führt „der Rest der Berechnung“ nimmt und die „Antwort“. Was die Frage beantworten hat und was Sie unter „dem Rest der Berechnung“ hängt davon ab, was Sie verwenden CPS für . CPS ist in der Regel kein Selbstzweck, sondern ist mit einem Zweck im Auge getan. Zum Beispiel in CPS Form ist es sehr einfach Bekämpfer oder zu optimieren Endrekursion zu implementieren. Ohne zu wissen, was Sie versuchen zu erreichen, ist es schwer, Ihre Frage zu beantworten.
Für das, was ist es wert, wenn Sie versuchen einfach, von den direkten Stil Fortsetzung Umgehung Stil zu konvertieren, und alles, was Sie über Pflege ist der Wert der Antwort, vorbei an die Identitätsfunktion als die Fortsetzung über rechts ist.
Ein guter nächster Schritt wäre evenk
zu implementieren CPS verwenden. Ich werde ein einfacheres Beispiel tun.
Wenn ich die direkte Stil Funktion
let muladd x i n = x + i * n
und wenn ich CPS Primitiven mulk
und addk
annehmen, kann ich schreiben
let muladdk x i n k =
let k' product = addk x product k in
mulk i n k'
Und Sie werden sehen, dass die mulptiplication zuerst getan wird, dann ist es „fährt fort“ mit k'
, die das Add tut, und schließlich, dass continues
mit k
, die Rückkehr an den Anrufer. Die Schlüsselidee ist, dass ich im Körper muladdk
eine frische Fortsetzung k'
zugeordnet, die in der Multiply-Add-Funktion für einen Zwischenpunkt steht. Um Ihre evenk
Arbeit machen Sie mindestens eine solche Fortsetzung zuweisen müssen.
Ich hoffe, das hilft.
Andere Tipps
Jedes Mal, wenn ich mit CPS gespielt habe, die Sache auf die Fortsetzung vergangen ist genau das, was Sie in der Regel an den Anrufer zurückkommen würden. In diesem einfachen Fall eine schöne „Intuition Schmiermittel“ ist die Fortsetzung „Rückkehr“ zu nennen.
let rec even list return =
if List.length list = 0
then return true
else if List.hd list mod 2 = 1
then return false
else even (List.tl list) return;;
let id = fun x -> x;;
Beispiel Nutzung:. "Even [2; 4; 6; 8] id ;;"
Da Sie den Aufruf von evenk
korrekt (mit der Identitätsfunktion -, dass die Fortsetzung-Passing-Stil wieder in dem normalen Stil Umwandlung) haben, gehe ich davon aus, dass die Schwierigkeit bei der Definition evenk
ist
k
ist die Fortsetzungsfunktion den Rest der Berechnung darstellt, und einen Endwert Herstellung, wie Norman gesagt. Also, was Sie tun müssen, ist das Ergebnis der v
von even
zu berechnen und das Ergebnis an k
passieren, Rückkehr k v
anstatt nur v
.
Sie mögen das Ergebnis Ihrer Funktion als Input geben, als ob es nicht mit Fortsetzung vorbei Stil geschrieben wurde.
Hier ist Ihre Funktion, die prüft, ob eine Liste nur noch ganze Zahlen hat:
(* val even_list : int list -> bool *)
let even_list input = List.for_all (fun x -> x mod 2=0) input
Nun wollen wir schreiben es mit einer Fortsetzung cont
:
(* val evenk : int list -> (bool -> 'a) -> 'a *)
let evenk input cont =
let result = even_list input in
(cont result)
Sie berechnen das Ergebnis Ihrer Funktion und übergeben result
to die Fortsetzung ...