RosettaCodeData/Task/Bernoulli-numbers/Haskell/bernoulli-numbers-2.hs
2023-07-01 13:44:08 -04:00

56 lines
1.3 KiB
Haskell

import Data.Bool (bool)
import Data.Ratio (Ratio, denominator, numerator, (%))
-------------------- BERNOULLI NUMBERS -------------------
bernouillis :: Integer -> [Rational]
bernouillis =
fmap head
. tail
. scanl faulhaber []
. enumFromTo 0
faulhaber :: [Ratio Integer] -> Integer -> [Ratio Integer]
faulhaber rs n =
(:) =<< (-) 1 . sum $
zipWith ((*) . (n %)) [2 ..] rs
--------------------------- TEST -------------------------
main :: IO ()
main = do
let xs = bernouillis 60
w = length $ show (numerator (last xs))
putStrLn $
fTable
"Bernouillis from Faulhaber triangle:\n"
(show . fst)
(showRatio w . snd)
id
(filter ((0 /=) . snd) $ zip [0 ..] xs)
------------------------ FORMATTING ----------------------
fTable ::
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
let w = maximum (length . xShow <$> xs)
in unlines $
s :
fmap
( ((<>) . rjust w ' ' . xShow)
<*> ((" -> " <>) . fxShow . f)
)
xs
showRatio :: Int -> Rational -> String
showRatio w r =
let d = denominator r
in rjust w ' ' $ show (numerator r)
<> bool [] (" / " <> show d) (1 /= d)
rjust :: Int -> a -> [a] -> [a]
rjust n c = drop . length <*> (replicate n c <>)