I have a clearly tail-recursive function for finding (choose n k) mod
10007 (with k nonnegative)
Why is this function consuming lots of memory for large inputs? (ie 100000000 choose 50000000) I can understand if it might be slow, but it shouldn't use more than constant memory, should it? (assuming GHC knows about tail-call optimization)
GHC version 7.8.3
modulus :: Int
modulus = 10007
choose :: Int -> Int -> Int
choose n1 k1
| s1 > 0 = 0
| otherwise = q1
where
(q1, s1) = doChoose n1 k1 (1, 0)
doChoose :: Int -> Int -> (Int, Int) -> (Int, Int)
doChoose _ 0 (qr, sr) = (qr, sr)
doChoose n k (qr, sr) =
doChoose (n `seq` (n-1)) (k-1) (qr `seq` (qn * qr `rem` modulus * inv qk `rem` modulus), sr `seq` (sn + sr - sk))
where
(qn, sn) = removePs n
(qk, sk) = removePs k
removePs :: Int -> (Int, Int)
removePs n =
case r of
0 -> (q0, s0 + 1)
_ -> (n, 0)
where
(q, r) = n `quotRem` modulus
(q0, s0) = removePs q
inv :: Int -> Int
inv = doInv 0 1 modulus . (`mod` modulus)
where
doInv x _ 1 0
| x < 0 = x + modulus
| otherwise = x
doInv _ _ _ 0 = error "Not relatively prime"
doInv x y a b = doInv y (x - q * y) b r
where
(q, r) = a `quotRem` b