Check Machin-like formulas: Difference between revisions

Line 48:
tans :: (Integral a, Fractional b) => [(a, b)] -> b
tans = foldl' tanPlus 0 . map tanEval
 
machins = [
[(1, 1%2), (1, 1%3)],
[(2, 1%3), (1, 1%7)],
[(12, 1%18), (8, 1%57), (-5, 1%239)],
[(88, 1%172), (51, 1%239), (32 , 1%682), (44, 1%5357), (68, 1%12943)]]
 
not_machin = [(88, 1%172), (51, 1%239), (32 , 1%682), (44, 1%5357), (68, 1%12944)]
 
main = do
putStrLn "Machins:"
mapM_ (\x -> putStrLn $ show (tans x) ++ " <-- " ++ show x) machins
 
putStr "\nnot Machin: "; print not_machin
print (tans not_machin)</lang>
 
A crazier way to do the above, exploiting the built-in exponentiation algorithms:
<lang haskell>import Data.Ratio
 
-- Private type. Do not use outside of the tans function
newtype Tan a = Tan a deriving (Eq, Show)
instance Fractional a => Num (Tan a) where
_ + _ = undefined
Tan a * Tan b = Tan $ (a + b) / (1 - a * b)
negate _ = undefined
abs _ = undefined
signum _ = undefined
fromInteger 1 = Tan 0 -- identity for the (*) above
fromInteger _ = undefined
instance Fractional a => Fractional (Tan a) where
fromRational _ = undefined
recip (Tan f) = Tan (-f) -- inverse for the (*) above
 
tans :: (Integral a, Fractional b) => [(a, b)] -> b
tans xs = x where
Tan x = product [Tan f ^^ coef | (coef,f) <- xs]
 
machins = [
Anonymous user