[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