{-# LANGUAGE FlexibleInstances #-}
module Math.Factorial where
import Data.Complex
import qualified Data.Vector.Unboxed as V
import GHC.Float (double2Float)
class Num a => Factorial a where
factorial :: Integral b => b -> a
factorial = Integer -> a
forall a. Num a => Integer -> a
fromInteger (Integer -> a) -> (b -> Integer) -> b -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Integer
forall a b. (Factorial a, Integral b) => b -> a
factorial
instance Factorial Integer where
factorial :: b -> Integer
factorial b
n
| b
n b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
0 = [Char] -> Integer
forall a. HasCallStack => [Char] -> a
error [Char]
"factorial: n < 0"
| Bool
otherwise = [Integer] -> Integer
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [Integer
1..b -> Integer
forall b. Integral b => b -> Integer
toInteger b
n]
instance Factorial Float where
factorial :: b -> Float
factorial = Double -> Float
double2Float (Double -> Float) -> (b -> Double) -> b -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Double
forall a b. (Factorial a, Integral b) => b -> a
factorial
instance Factorial (Complex Float) where
factorial :: b -> Complex Float
factorial = (Float -> Float -> Complex Float
forall a. a -> a -> Complex a
:+ Float
0) (Float -> Complex Float) -> (b -> Float) -> b -> Complex Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Float
forall a b. (Factorial a, Integral b) => b -> a
factorial
instance Factorial Double where
factorial :: b -> Double
factorial b
n
| b
n b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
0 = Double
0Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
0
| b
n b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
forall a. Num a => a
nFacs = Vector Double
facs Vector Double -> Int -> Double
forall a. Unbox a => Vector a -> Int -> a
V.! b -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
n
| Bool
otherwise = Double
infinity
where
nFacs :: Num a => a
nFacs :: a
nFacs = a
171
facs :: Vector Double
facs = (Double -> Double -> Double)
-> Double -> Vector Double -> Vector Double
forall a b.
(Unbox a, Unbox b) =>
(a -> b -> a) -> a -> Vector b -> Vector a
V.scanl Double -> Double -> Double
forall a. Num a => a -> a -> a
(*) Double
1 (Double -> Int -> Vector Double
forall a. (Unbox a, Num a) => a -> Int -> Vector a
V.enumFromN Double
1 Int
forall a. Num a => a
nFacs)
infinity :: Double
infinity = Vector Double
facs Vector Double -> Int -> Double
forall a. Unbox a => Vector a -> Int -> a
V.! Int
forall a. Num a => a
nFacs
instance Factorial (Complex Double) where
factorial :: b -> Complex Double
factorial = (Double -> Double -> Complex Double
forall a. a -> a -> Complex a
:+ Double
0) (Double -> Complex Double) -> (b -> Double) -> b -> Complex Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Double
forall a b. (Factorial a, Integral b) => b -> a
factorial