2016-07-09 3 views
0

Gegeben:Verständnis `RunEval` - Nicht WHNF?

Prelude> import Control.Parallel.Strategies 
Prelude> import Control.Parallel 
Prelude> let fact n = if (n <= 0) then 1 else n * fact (n-1) :: Integer 
Prelude> let xs = map (runEval . (\x -> return x :: Eval Integer) . fact) [1..100] 
Prelude> let ys = map fact [1..100] 
Prelude> :sprint xs 
xs = _ 
Prelude> :sprint ys 
ys = _ 

Wie ich verstehe, xs ist in Weak Kopf Normalform. Warum das? Hat die runEval keinen Einfluss darauf, den Wert/die Berechnung in die Normalform zu bringen?

+0

Warum der Downvote? –

+0

Wahrscheinlich, weil Sie nicht angegeben haben, woher 'runEval' oder' Eval' kommen. –

+0

danke, David. Ich habe normalerweise 'import's - meinen Fehler. –

Antwort

2

Der Grund ist, dass let nur einen Namen mit einem Ausdruck bindet, aber es keine Auswertung des Ausdrucks auslöst.

Um besser zu verstehen, lassen Sie mich

Main> let x = error "foobar!" in 1 
1 

ein einfaches Beispiel verwenden Wie Sie sehen können, die error "foobar!", dass Ausnahme auslösen soll, wird einfach ignoriert. Der Grund ist, dass x nicht verwendet wird und Haskell es nicht auswertet. Sie brauchen etwas, die Auswertung von x

Main> let x = error "foobar!" in x `seq` 1 
*** Exception: foobar! 

Gehen wir zurück zu Ihrem Beispiel zu triggern, beachten Sie, dass Eval x gibt an, wie ein x zu bewerten, nicht, wenn es in Ihrem Programm ausgewertet werden.

Werfen Sie einen Blick auf diesen Wiki-Artikel auf Lazyness für mehr.