In Haskell, könnte ich if
wie folgt implementieren:Idris eifrig Bewertung
if' True x y = x
if' False x y = y
spin 0 =()
spin n = spin (n - 1)
Diese verhält, wie ich erwarte, dass:
haskell> if' True (spin 1000000)() -- takes a moment
haskell> if' False (spin 1000000)() -- immediate
In Racket, konnte ich implementieren Sie eine fehlerhafte if
wie folgt:
(define (if2 cond x y) (if cond x y))
(define (spin n) (if (= n 0) (void) (spin (- n 1))))
Diese verhält, wie ich erwarte, dass:
racket> (if2 #t (spin 100000000) (void)) -- takes a moment
racket> (if2 #f (spin 100000000) (void)) -- takes a moment
In Idris, könnte ich if
wie folgt implementieren:
if' : Bool -> a -> a -> a
if' True x y = x
if' False x y = y
spin : Nat ->()
spin Z =()
spin (S n) = spin n
Dieses Verhalten surpris ES mich:
idris> if' True (spin 1000)() -- takes a moment
idris> if' False (spin 1000)() -- immediate
ich Irdis wie Racket verhalten erwartet, wo beide Argumente sind ausgewertet. Aber das ist nicht der Fall!
Wie entscheidet Idris, wann die Dinge bewertet werden?
Danke! Ich musste 'Spin: Nat ->()' zu 'Spin: Nat -> Bool' ändern (Ich vermute, dass Idris realisiert'() 'hat nur einen Einwohner und optimiert den Aufruf zum' Spin'), aber danach dass die ausführbare Datei einen Moment brauchte, um zu laufen, unabhängig davon, welcher Zweig des 'if'-Befehls ausfiel. – Snowball
Ja, es hätte das() gelöscht. Eigentlich im aktuellen Master tut es eine viel tiefere Löschung Analyse, so dass Sie wahrscheinlich etwas wie das Drucken des Ergebnisses von Spin n tun müssen, um sicherzustellen, dass es ausgewertet wurde ... –
Wie kommt es, wenn es bekannt ist, dass "Spin 1000" ist Beenden und haben keine Nebenwirkungen, dass dieser Ausdruck nicht zur Kompilierzeit ausgewertet und durch sein Ergebnis im generierten Code ersetzt wird, so dass beide Versionen der 'if'-Zeile ihr Ergebnis sofort zur Laufzeit zurückgeben würden? (Snowballs Kommentar oben zeigt an, dass dies nicht der Fall ist.) – Lii