Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

laziness in action? (Haskell)

In chapter 6 of Learn You a Haskell, the following function is introduced:

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys

The author gives a couple examples of its use which I found easy enough to follow. Then this one:

ghci> zipWith' (zipWith' (*)) [[1,2,3],[3,5,6],[2,3,4]] [[3,2,2],[3,4,5],[5,4,3]]

Which outputs [[3,4,6],[9,20,30],[10,12,12]]

Is this an example of lazy evaluation? I tried to translate zipWith' into Scheme (see below). I got it working with the "easy" examples, but not the last one, which makes me think that Haskell's laziness might be making the difference.

(define zipWith
  (lambda (f listA listB)
    (cond
      ((null? listA) (quote ()))
      ((null? listB) (quote ()))
      (else (cons (f (car listA) (car listB)) (zipWith f (cdr listA) (cdr listB)))))))
like image 868
planarian Avatar asked Dec 11 '25 13:12

planarian


2 Answers

No, although this example will be evaluated lazily (like any other function in Haskell), the behaviour doesn't depend on that. On finite lists it would behave the same way with eager evaluation. On infinite lists, of course, it would never terminate with eager evaluation, but lazy evaluation allows you to evaluate only as many list elements as you need.

If you post the code you're using to call the Scheme zipWith for the last example, maybe we can help see why that's behaving differently.

like image 139
Dan Hulme Avatar answered Dec 13 '25 08:12

Dan Hulme


zipWith' (*) [1,2,3] [1..] would (have use of) evaluate lazily

like image 41
Viktor Mellgren Avatar answered Dec 13 '25 09:12

Viktor Mellgren



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!