Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a lazier sum function in haskell?

How could i make the left hand sum in the expression below "less strict" such that i don't evaluate the whole list xs. In the example, only the first 3 elements are enough to know the result of the second expression (True).

xs=[1..10]
sum xs > 3

ghci:

λ> let xs = [1..10]
λ> :sp xs
xs = _
λ> sum xs > 3
True
λ> :sp xs
xs = [1,2,3,4,5,6,7,8,9,10] 
like image 213
vis Avatar asked Feb 16 '23 03:02

vis


1 Answers

Use a lazy natural.

Prelude Data.Number.Natural> let xs = [1..10] :: [Natural]
Prelude Data.Number.Natural> :sp xs
xs = _
Prelude Data.Number.Natural> sum xs > 3
True
Prelude Data.Number.Natural> :sp xs
xs = [Data.Number.Natural.S Data.Number.Natural.Z,
      Data.Number.Natural.S
        (Data.Number.Natural.S Data.Number.Natural.Z),
      Data.Number.Natural.S _,_,_,_,_,_,_,_]

To go even lazier, use foldr instead of foldl the way sum does:

Prelude Data.Number.Natural> let xs = [1..10] :: [Natural]
Prelude Data.Number.Natural> let lazySum = foldr (+) 0
Prelude Data.Number.Natural> lazySum xs > 3
True
Prelude Data.Number.Natural> :sp xs
xs = Data.Number.Natural.S Data.Number.Natural.Z :
     Data.Number.Natural.S
       (Data.Number.Natural.S Data.Number.Natural.Z) :
     Data.Number.Natural.S _ : _
like image 56
Daniel Wagner Avatar answered Feb 24 '23 15:02

Daniel Wagner