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
```