import Data.Ratio
ltPi :: Rational -> Bool
ltPi x = ok x 1 where ok y i = y <= 2 || (y < 4 && ok ((y - 2)*(2 + 1%i)) (i + 1))
piApprox :: [Rational]
piApprox = go 2 4 where
go p q = m : if ltPi m then go m q else go p m where
m = (numerator p + numerator q)%(denominator p + denominator q)
piConvergents :: [Rational]
piConvergents = go True 2 4 where
go s p q | ltPi m = [q | not s] ++ go True m q
| otherwise = [p | s] ++ go False p m where
m = (numerator p + numerator q)%(denominator p + denominator q)
main :: IO ()
main = do
putStrLn "Approximations:"
mapM_ print (take 20 piApprox)
putStrLn "Convergents:"
mapM_ print (take 20 piConvergents)