0 | module Utils.Num
 1 |
 2 | import Data.Vect
 3 |
 4 | alphabets : Vect 36 Char
 5 | alphabets = fromList $ unpack "0123456789abcdefghijklmnopqrstuvwxyz"
 6 |
 7 | -- Use integer for performance reason
 8 | export
 9 | stringToNat' : Fin 36 -> String -> Maybe Integer
10 | stringToNat' base str = if str == "" then Nothing else go (finToInteger base) 1 0 $ reverse $ unpack str
11 |   where
12 |     go : Integer -> Integer -> Integer -> List Char -> Maybe Integer
13 |     go base' yoyo acc [] = Just acc
14 |     go base' yoyo acc (chr :: xs) = do
15 |       i <- elemIndex chr alphabets
16 |       if i < base then go base' (base' * yoyo) (acc + finToInteger i * yoyo) xs else Nothing
17 |
18 | export
19 | stringToNat : Fin 36 -> String -> Maybe Nat
20 | stringToNat base string = integerToNat <$> stringToNat' base string
21 |
22 | export
23 | stringToInteger : Fin 36 -> String -> Maybe Integer
24 | stringToInteger base str =
25 |   case strUncons str of
26 |     Just ('-', num) => negate <$> stringToNat' base num
27 |     Just ('+', num) => stringToNat' base num
28 |     _ => stringToNat' base str
29 |