
Hello Daniel I can get close with a tail recursive + accumulator monoidal unfoldr and strict triple for the state (leibniz4). But it does seem to be loosing the point of the initial exercise "to be idiomatic", also the answers are divergent too... Best wishes Stephen ------ Leibniz4 - monodial unfoldr strict triple ------ $ ./Leibniz4 +RTS -sstderr -RTS d:\coding\haskell\cafe\Leibniz4.exe +RTS -sstderr EPS: PI mit EPS 1.0e-8 = 3.1415926526069526 24,424 bytes allocated in the heap 892 bytes copied during GC 3,068 bytes maximum residency (1 sample(s)) 13,316 bytes maximum slop 1 MB total memory in use (0 MB lost due to fragmentation) Generation 0: 0 collections, 0 parallel, 0.00s, 0.00s elapsed Generation 1: 1 collections, 0 parallel, 0.00s, 0.00s elapsed INIT time 0.03s ( 0.00s elapsed) MUT time 4.34s ( 4.45s elapsed) GC time 0.00s ( 0.00s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 4.38s ( 4.45s elapsed) %GC time 0.0% (0.0% elapsed) Alloc rate 5,582 bytes per MUT second Productivity 99.3% of total user, 97.5% of total elapsed ------ Leibniz1 - stream fusion ------ $ ./Leibniz1 +RTS -sstderr -RTS d:\coding\haskell\cafe\Leibniz1.exe +RTS -sstderr EPS: PI mit EPS 1.0e-8 = 3.1415926445727678 24,404 bytes allocated in the heap 892 bytes copied during GC 3,068 bytes maximum residency (1 sample(s)) 13,316 bytes maximum slop 1 MB total memory in use (0 MB lost due to fragmentation) Generation 0: 0 collections, 0 parallel, 0.00s, 0.00s elapsed Generation 1: 1 collections, 0 parallel, 0.00s, 0.00s elapsed INIT time 0.02s ( 0.00s elapsed) MUT time 4.61s ( 4.63s elapsed) GC time 0.00s ( 0.00s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 4.63s ( 4.63s elapsed) %GC time 0.0% (0.0% elapsed) Alloc rate 5,276 bytes per MUT second Productivity 99.7% of total user, 99.7% of total elapsed ---------- module Main (main) where import Data.Monoid data Maybe2 a st = Nothing2 | Just2 a !st deriving (Eq,Show) dummy_eps :: Double dummy_eps = 0.00000001 main :: IO () main = do putStrLn "EPS: " eps <- return dummy_eps let mx = floor (4/eps) !k = (mx+1) `quot` 2 putStrLn $ "PI mit EPS " ++ (show eps) ++ " = " ++ show (leibniz k) leibniz :: Integer -> Double leibniz n = (4 *) $ getSum $ step (fromIntegral n) data Trip = T3 !Int !Bool !Double step :: Int -> Sum Double step times = unfoldrMon phi (T3 0 True 1) where phi :: Trip -> Maybe2 (Sum Double) Trip phi (T3 i _ _) | i == times = Nothing2 phi (T3 i sig d) | sig = Just2 (Sum (1/d)) (T3 (i+1) False (d+2)) | otherwise = Just2 (Sum (negate (1/d))) (T3 (i+1) True (d+2)) unfoldrMon :: Monoid a => (b -> Maybe2 a b) -> b -> a unfoldrMon f b0 = step b0 mempty where step b acc = case f b of Nothing2 -> acc Just2 a new_b -> step new_b (a `mappend` acc)