
Current type signature of readIntP is: readIntP :: Num a => a -> (Char -> Bool) -> (Char -> Int) -> ReadP a This seems kinda redundant. It inputs two functions, one checking whether a character is valid digit, and the other assigning an integer to the digit. Shouldn't we merge them together to one function? Like this: import Control.Monad import Data.Foldable import Data.Maybe import Text.ParserCombinators.ReadP readIntP :: Num a => a -> (Char -> Maybe Int) -> ReadP a readIntP base valDigit = do maybeNs <- manyTill (fmap (fmap fromIntegral . valDigit) get) $ do str <- fmap (fmap valDigit) look case str of [] -> return () (Nothing:_) -> return () _ -> pfail let n = foldl' (\l r -> case l of Nothing -> r Just l1 -> fmap (base * l1 +) r ) Nothing maybeNs guard (isJust n) return (fromJust n)