Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To what extent is Haskell lazy?

I need some clarification about laziness with Haskell.

If I have this function:

myFunction arg   | arg == 1 = a   | arg == 2 = a*b   | arg == 3 = b+c   | otherwise = (a+b)*c      where             a = ...             b = ...             c = ...             d = ... 

When I call myFunction 1, Haskell will evaluate only the a = ... function, neither b nor c, nor d.

But if I write

myFunction arg   | arg == 1 = a   | arg == 2 = a*b   | arg == 3 = b+c   | otherwise = (a+b)*c      where             (a,b,c,d) = anotherFunction arg 

What will Haskell's behaviour be?

  • Will it evaluate only a and 'propagate' the lazyness to anotherFunction?
  • Or, will it evaluate the whole tuple (a,b,c,d) as result of anotherFunction?
like image 845
JeanJouX Avatar asked Mar 31 '15 10:03

JeanJouX


People also ask

Is Haskell lazy evaluation?

Haskell is a lazy language, meaning that it employs lazy evaluation . Before explaining lazy evaluation , let's first explain strict evaluation which most readers will likely be more familiar with. Strict evaluation means that arguments to functions are evaluated prior to being passed to the functions.

Is Haskell lazy or eager?

Haskell is often described as a lazy language.

Why is Haskell lazy?

Haskell is a lazy language. It does not evaluate expressions until it absolutely must. This frequently allows our programs to save time by avoiding unnecessary computation, but they are at more of a risk to leak memory. There are ways of introducing strictness into our programs when we don't want lazy evaluation.

Does Haskell support lazy processing?

Haskell uses a special form of evaluation called lazy evaluation. In lazy evaluation, no code is evaluated until it's needed. In the case of longList , none of the values in the list were needed for computation.


2 Answers

In both cases, it won't evaluate anything unless the value is demanded. One way of demanding the value is calling the function in ghci (which prints the value in ghci and hence demanding it). Assuming that you are executing the function, then in your second case it will evaluate the tuple to weak head normal form (WHNF) and then evaluate the first element in (a,b,c,d) because only that value is demanded. The other elements b, c and d will be in the thunk form. In fact you can verify that yourself:

myFunction arg   | arg == 1 = a   | arg == 2 = a*b   | arg == 3 = b+c   | otherwise = (a+b)*c   where     (a,b,c,d) = anotherFunction arg  anotherFunction x = (x, undefined, undefined, undefined) 

Demo in ghci:

λ> myFunction 1 1 
like image 84
Sibi Avatar answered Oct 03 '22 20:10

Sibi


Well it is only interested in a, so that means that there is an implicit function:

thea :: (a,b,c,d) -> a thea (a,_,_,_) = a 

In other words Haskell is not interested in the other elements of the tuple. Sometimes however the elements of the tuple share some structure. Say another function is defined as:

anotherFunction :: Int -> (Int,Int,Int,Int) anotherFunction x = (z,t,f,g)     where f = x*x           g = f+x           z = g-2           t = 3 

In that case - in order to evaluate the first element - the third and fourth element will also be evaluated. But since you don't do anything with them, Haskell won't be interested in their result specifically.

like image 26
Willem Van Onsem Avatar answered Oct 03 '22 20:10

Willem Van Onsem