These are a couple of best-practices the code is lacking. I infact already answered the question itself.
1- do not use tuples as input. in Haskell, functions can have multiple parameters. the syntax is f x y
for calling f
on x
and y
. the types also have similar syntax. this transforms your code to:
fac 1 = 1
fac n = fac (n-1) * n
--prob :: (Integral b, Fractional b) => b -> b -> b (two parameters of type b and output of type b)
--prob :: Int -> Int -> Double
prob n k
| n==k = (0.01**k)
| otherwise = factor n k * (0.01 ** k) * (0.99**(n-k)) + prob n (k+1)
where
factor n k = (fac n / ((fac k)* (fac (n-k))))
2- if you will notice, fac
will only work on Integers, and similarly does factor
. prob infact then has type of (Fractional a, Integral b) -> b -> b -> a
or alternatively Integer -> Integer -> Float
. why not give them their true type?
this transformation requires changing **
(which gets two floating point numbers) to ^
(which gets an Integer as it's second parameter) and using the function fromIntegral
which casts an Integer to an arbitrary number Data.
fac :: Integral a => a -> a -- or alternatively Integer -> Integer
fac 1 = 1
fac n = fac (n-1) * n
prob n k
| n==k = (0.01 ^^ k)
| otherwise = fromIntegral (factor n k) * (0.01 ^^ k) * (0.99 ^^ (n-k) + prob n (k+1)
where
factor n k = div (fac n) (fac k * fac (n-k)) -- div is Integer division operator.
now prob
has type of (Integral a, Floating b) => a -> a -> b
which means it gets two parameters of type a
(which is an Integral instance) and returns a value of type b
.