Understanding `runEval` - Not WHNF? - haskell

Given:
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 = _
As I understand, xs is in Weak Head Normal Form. Why is that? Didn't the runEval have any affect on bringing the value/computation to Normal Form?

The reason is that let just binds a name with an expression but it doesn't trigger any evaluation of the expression.
To understand better, let me use a more simple example
Main> let x = error "foobar!" in 1
1
As you can see, the error "foobar!", that should throw exception, is just ignored. The reason is that x is not used and thus Haskell doesn't evaluate it. You need something to trigger the evaluation of x
Main> let x = error "foobar!" in x `seq` 1
*** Exception: foobar!
Going back to your example, note that Eval x specifies how to evaluate a x, not when it will be evaluated in your program.
Have a look at this wiki article on Lazyness for more.

Related

Strict list evaluation in GHCi

Consider the program:
l = [0..10]
l' = map (+1) [0..10]
Running it with GHCi, and typing :sprint l and :sprint l' will reveal both lists to be unevaluated. However, after running length l and length l' and then again using sprint:
l = [0,1,2,3,4,5,6,7,8,9,10]
and
l' = [_,_,_,_,_,_,_,_,_,_,_]
I've made similar experiments and tried binding variables to lists in GHCi with let, however only in the case of l (defined as above in a program top-level) is the list always completely evaluated.
These behaviours all point to an optimisation feature, however I was wondering if there is a more elaborate answer (strategy) 'under-the-hood'.
The elements of the original [0..10] lists were evaluated in both cases. What was left unevaluated in the l' case were the results of applying (+1) to the list elements. In contrast, here is what happens if we map the function strictly:
GHCi> import Control.Monad
GHCi> l'' = (+1) <$!> [0 :: Integer ..10]
GHCi> :sprint l''
l'' = _
GHCi> length l''
11
GHCi> :sprint l''
l'' = [1,2,3,4,5,6,7,8,9,10,11]
(Note that I am specialising the integer literals, so that the absence of the monomorphism restriction in the GHCi prompt doesn't lead to different results from what you get upon loading the code from a file.)
It is worth noting that enumFromTo for Integer (which is what using the range boils down to), as implemented by base, evaluates the elements in order to know when to stop generating them. That's to say it is not length that forces the list elements, as we'd hope from looking at its definition:
length :: [a] -> Int
length xs = lenAcc xs 0
lenAcc :: [a] -> Int -> Int
lenAcc [] n = n
lenAcc (_:ys) n = lenAcc ys (n+1)
To get a better feeling for how length behaves here, we might try repeating your experiment with a list generated by using replicate (which, like length, doesn't look at the elements) on a not fully evaluated value:
GHCi> n = 2 * (7 :: Integer) -- let-bindings are lazy.
GHCi> :sprint n
n = _
GHCi> l''' = replicate 3 n
GHCi> :sprint l'''
l''' = _
GHCi> length l'''
3
GHCi> :sprint l'''
l''' = [_,_,_]

Patching a recursively-defined list without a <<loop>>

Context
We all know the recursively-defined Fibonacci sequence:
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
λ> fibs
[1,1,2,3,5,9,13,21,34,55,89...
Question
I'm trying to “patch” it in a few places, so that:
the general recursive equation “element is sum of two previous elements” holds, but
there can be countable exceptions as to individual elements' values.
Where I'm at
Utility
To this end, I'll define the following function to modify a specific element in a list:
patch :: Int -> a -> [a] -> [a]
patch i v xs = left ++ v : right where (left,_:right) = splitAt i xs
I can use it to change the sequence of naturals:
λ> patch 5 0 [0..]
[0,1,2,3,4,0,6,7,8,9...
Post-patch
So far, so good. Now to patch the Fibonacci sequence:
λ> patch 1 0 fibs
[1,0,2,3,5,8,13,21,34,55,89...
This fulfills requirement (2).
Full patch
To get (1) as well, I'll rewrite the definition in a more explicit tie-the-knot style:
fibs' p = rec where rec = p (1 : 1 : zipWith (+) rec (tail rec))
With no patch, it still works as expected:
λ> fibs' id
[1,1,2,3,5,9,13,21,34,55,89...
And I now can patch the element I want and keep the recursive definition:
λ> fibs' (patch 1 0)
[1,0,1,1,2,3,5,8,13,21,34...
Limitation
But can I?
λ> fibs' (patch 5 0)
<<loop>>
Problem
What's wrong?
Intuitively, the dataflow seems sound. Every list element ought to have a proper definition that does not involve loops. I mean, it was good enough for no-patch fibs; the patching only ought to make it more defined.
So I'm probably missing something. Some strictness issue with my patch function? Some strictness issue elsewhere? Something else entirely?
You're a bit stricter than you mean to be. Look at
patch i v xs = left ++ v : right where (left,_:right) = splitAt i xs
I believe you intend that xs is guaranteed to have at least i elements. But splitAt doesn't know that. You can likely fix your program using your own splitter.
splitAtGuaranteed :: Int -> [a] -> ([a], [a])
splitAtGuaranteed 0 xs = ([], xs)
splitAtGuaranteed n ~(x:xs) = first (x :) $ splitAtGuaranteed (n - 1) xs
Edit
Daniel Wagner points out that you don't need all the laziness (or the partiality) of splitAtGuaranteed. It's enough to be just a tiny bit lazier:
patch i v xs = left ++ [v] ++ drop 1 right where (left, right) = splitAt i xs

Why does not get evaluate? [duplicate]

Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
Why does it always print a _? I don't quite get the semantics of the :sprint command.
Haskell is a lazy language. It doesn't evaluate results until they are "needed".
Now, just printing a value causes all of it to be "needed". In other words, if you type an expression in GHCi, it will try to print out the result, which causes it all to be evaluated. Usually that's what you want.
The sprint command (which is a GHCi feature, not part of the Haskell language) allows you to see how much of a value has been evaluated at this point.
For example:
Prelude> let xs = [1..]
Prelude> :sprint xs
xs = _
So, we just declared xs, and it's currently unevaluated. Now let's print out the first element:
Prelude> head xs
1
Prelude> :sprint xs
xs = 1 : _
Now GHCi has evaluated the head of the list, but nothing more.
Prelude> take 10 xs
[1,2,3,4,5,6,7,8,9,10]
Prelude> :sprint xs
xs = 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : _
Now the first 10 elements are evaluated, but more remain. (Since xs is an infinite list, that's not surprising.)
You can construct other expressions and evaluate them a bit at a time to see what's going on. This is really part of the GHCi debugger, which lets you step through your code one bit at a time. Especially if your code is getting caught in an infinite loop, you don't want to print anything, because that might lock up GHCi. But you still want to see what's going on... hence sprint, which lets you see what's evaluated so far.
I'm a bit late, but I had a similar issue:
λ: let xs = [1,2,3]
xs :: Num t => [t]
λ: :sprint xs
xs = _
λ: print xs
λ: :sprint xs
xs = _
This issue is specific to polymorphic values. If you have -XNoMonomorphismRestriction enabled ghci will never really evaluate/force xs, it'll only evaluate/force specializations:
λ: :set -XMonomorphismRestriction
λ: let xs = [1,2,3]
xs :: [Integer]
λ: print xs
λ: :sprint xs
xs = [1,2,3]
Haskell is lazy. It doesn't evaluate things until they are needed.
The GHCi sprint command (not part of Haskell, just a debugging command of the interpreter) prints the value of an expression without forcing evaluation.
When you write
let a = 3
you bind a new name a to the right-hand side expression, but Haskell won't evaluate that thing yet. Therefore, when you sprint it, it prints _ as the value to indicate that the expression has not yet been evaluated.
Try this:
let a = 3
:sprint a -- a has not been evaluated yet
print a -- forces evaluation of a
:sprint a -- now a has been evaluated

Haskell tester for evaluation / apply steps taken by the parser? [duplicate]

Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
Why does it always print a _? I don't quite get the semantics of the :sprint command.
Haskell is a lazy language. It doesn't evaluate results until they are "needed".
Now, just printing a value causes all of it to be "needed". In other words, if you type an expression in GHCi, it will try to print out the result, which causes it all to be evaluated. Usually that's what you want.
The sprint command (which is a GHCi feature, not part of the Haskell language) allows you to see how much of a value has been evaluated at this point.
For example:
Prelude> let xs = [1..]
Prelude> :sprint xs
xs = _
So, we just declared xs, and it's currently unevaluated. Now let's print out the first element:
Prelude> head xs
1
Prelude> :sprint xs
xs = 1 : _
Now GHCi has evaluated the head of the list, but nothing more.
Prelude> take 10 xs
[1,2,3,4,5,6,7,8,9,10]
Prelude> :sprint xs
xs = 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : _
Now the first 10 elements are evaluated, but more remain. (Since xs is an infinite list, that's not surprising.)
You can construct other expressions and evaluate them a bit at a time to see what's going on. This is really part of the GHCi debugger, which lets you step through your code one bit at a time. Especially if your code is getting caught in an infinite loop, you don't want to print anything, because that might lock up GHCi. But you still want to see what's going on... hence sprint, which lets you see what's evaluated so far.
I'm a bit late, but I had a similar issue:
λ: let xs = [1,2,3]
xs :: Num t => [t]
λ: :sprint xs
xs = _
λ: print xs
λ: :sprint xs
xs = _
This issue is specific to polymorphic values. If you have -XNoMonomorphismRestriction enabled ghci will never really evaluate/force xs, it'll only evaluate/force specializations:
λ: :set -XMonomorphismRestriction
λ: let xs = [1,2,3]
xs :: [Integer]
λ: print xs
λ: :sprint xs
xs = [1,2,3]
Haskell is lazy. It doesn't evaluate things until they are needed.
The GHCi sprint command (not part of Haskell, just a debugging command of the interpreter) prints the value of an expression without forcing evaluation.
When you write
let a = 3
you bind a new name a to the right-hand side expression, but Haskell won't evaluate that thing yet. Therefore, when you sprint it, it prints _ as the value to indicate that the expression has not yet been evaluated.
Try this:
let a = 3
:sprint a -- a has not been evaluated yet
print a -- forces evaluation of a
:sprint a -- now a has been evaluated

Performance of "all" in haskell

I got nearly no knowledge of haskell and tried to solve some Project Euler Problems.
While solving Number 5 I wrote this solution (for 1..10)
--Check if n can be divided by 1..max
canDivAll :: Integer -> Integer -> Bool
canDivAll max n = all (\x -> n `mod` x == 0) [1..max]
main = print $ head $ filter (canDivAll 10) [1..]
Now I found out, that all is implemented like this:
all p = and . map p
Doesn't this mean, the condition is checked for every element? Wouldn't it be much faster to break upon the first False-Result of the condition? This would make the execution of the code above faster.
Thanks
and itself is short-circuited and since both map and all evaluation is lazy, you will only get as many elements as needed - not more.
You can verify that with a GHCi session:
Prelude Debug.Trace> and [(trace "first" True), (trace "second" True)]
first
second
True
Prelude Debug.Trace> and [(trace "first" False), (trace "second" False)]
first
False
map does not evaluate all its argument before and executes. And and is short-circuited.
Notice that in GHC all isn't really defined like this.
-- | Applied to a predicate and a list, 'all' determines if all elements
-- of the list satisfy the predicate.
all :: (a -> Bool) -> [a] -> Bool
#ifdef USE_REPORT_PRELUDE
all p = and . map p
#else
all _ [] = True
all p (x:xs) = p x && all p xs
{-# RULES
"all/build" forall p (g::forall b.(a->b->b)->b->b) .
all p (build g) = g ((&&) . p) True
#-}
#endif
We see that all p (x:xs) = p x && all p xs, so whenever p x is false, the evaluation will stop.
Moreover, there is a simplification rule all/build, which effectively transforms your all p [1..max] into a simple fail-fast loop*, so I don't think you can improve much from modifying all.
*. The simplified code should look like:
eftIntFB c n x0 y | x0 ># y = n
| otherwise = go x0
where
go x = I# x `c` if x ==# y then n else go (x +# 1#)
eftIntFB ((&&) . p) True 1# max#
This is a good program for the fusion optimization, as all your loops are expressed as fusible combinators. Thus you can write it using, e.g. Data.Vector, and get better performance than with lists.
From N=20, with lists as in your program:
52.484s
Also, use rem instead of mod.
15.712s
Where the list functions become vector operations:
import qualified Data.Vector.Unboxed as V
canDivAll :: Int -> Int -> Bool
canDivAll max n = V.all (\x -> n `rem` x == 0) (V.enumFromN 1 max)
main = print . V.head $ V.filter (canDivAll 20) $ V.unfoldr (\a -> Just (a, a+1)) 1
You're assuming that and is not short-circuiting. and will stop execution on the first false result it sees, so it is "fast" as one might expect.

Resources