[Haskell-beginners] Performance of Idiomatic lazy Haskell

Stephen Tetley stephen.tetley at gmail.com
Sun Jan 31 06:37:02 EST 2010


Hi Markus

I haven't tested the efficiency, but an unfold seems natural /
idiomatic in this case. The Leibniz formula generates a list in the
first step then sums it. Generating a list is often a perfect fit for
an unfold. The code below seems quite close to the idea of the Leibniz
formula (add 2 to the denominator, flip the sign at each step), sum
and multiple by 4.

> import Data.List (unfoldr)

> leibniz n = (4 *) $ sum $ take n step

-- Note this unfoldr generates an infinite list (both cases produce
Just values) ...

> step :: [Double]
> step = unfoldr phi (True,1) where
>   phi (sig,d) | sig == True = Just (1/d, (False,d+2))
>               | otherwise   = Just (negate (1/d), (True,d+2))



Alternatively, an unfoldr with a stop condition might seem more
natural, creating a bounded list. However, here it is a bit ugly
as there are now 3 elements in the unfold state:

> leibniz' n = (4 *) $ sum $ step' n

> step' :: Int -> [Double]
> step' n = unfoldr phi (0,True,1) where
>   phi (i,_,_)   | i   == n    = Nothing
>   phi (i,sig,d) | sig == True = Just (1/d, (i+1,False,d+2))
>                 | otherwise   = Just (negate (1/d), (i+1,True,d+2))


Best wishes

Stephen


More information about the Beginners mailing list