aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2017-08-20 13:03:37 +0200
committerTeddy Wing2017-08-20 15:15:14 +0200
commitc543eebfcbd92bb261003dbfd658487b59362a5b (patch)
tree1fca7a2b80dddf95eddcd9321bc79c5785adee9e /src
parentde7e162e6865b9e805154b7c7178406309746e6f (diff)
downloadsorbot-c543eebfcbd92bb261003dbfd658487b59362a5b.tar.bz2
Factorial: Use `Integer` instead of `Int` for bigger numbers
The `Integer` type has arbitrary precision. This is why the function was working fine in GCHi but overflowing when I was testing the bot. Use `Integer` to get the real values we want. https://stackoverflow.com/questions/36355757/large-numbers-become-negative-in-haskell Also add a little extra error handling to deal with unexpected numbers. Now that I think about it, the regex parser isn't going to handle negative numbers, so we're good on that front. Set an upper bound so we don't end up spending a lot of time trying to calculate numbers and potentially segfault if huge numbers are given.
Diffstat (limited to 'src')
-rw-r--r--src/Plugin/Factorial.hs13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/Plugin/Factorial.hs b/src/Plugin/Factorial.hs
index 692d20f..97730de 100644
--- a/src/Plugin/Factorial.hs
+++ b/src/Plugin/Factorial.hs
@@ -23,7 +23,14 @@ factorialAction message = do
[] -> return $ Left "I didn't understand"
(m:_) -> do
let number = last m
- return $ Right $ showt $ calculate $ (read number :: Int)
+ return $ Right $ result (read number :: Integer)
+ where
+ result n = case calculate n of
+ Nothing -> "Input is too large."
+ Just n -> showt n
-calculate :: (Integral a) => a -> a
-calculate n = product [1..n]
+calculate :: Integer -> Maybe Integer
+calculate n
+ | n <= 0 = Just 0
+ | n <= 35000 = Just $ product [1..n]
+ | otherwise = Nothing