Search code examples
parsinghaskellparsec

How to parse integer with base prefix using parsec in haskell?


I'm trying to parse an input integer string in haskell using parsec. The string might either be in decimal, octal or hexadecimal. The base is specified by a prefix of #d, #o or #x for decimal, octal and hexadecimal respectively, which is then followed by the integer. If no prefix is specified, the base is assumed to be 10. Here's what I've done so far:

parseNumber = do x <- noPrefix <|> withPrefix
             return x
          where noPrefix = many1 digit
                withPrefix = do char '#'
                                prefix <- oneOf "dox"
                                return $ case prefix of
                                    'd' -> many1 digit
                                    'o' -> fmap (show . fst . head . readOct) (many1 octDigit)
                                    'x' -> fmap (show . fst . head . readHex) (many1 hexDigit)

However, this isn't compiling and is failing with type errors. I don't quite really understand the type error and would just like help in general with this problem. Any alternative ways to solve it will also be appreciated.

Thank you for your time and help. :)

EDIT: Here's the error I've been getting.


Solution

  • You have two slight errors:

    One indention error (return x must be indented compared to do) and the parsers in withPrefix must not be returned, since they will return their results anyway.

    parseNumber = do x <- noPrefix <|> withPrefix
                     return x
          where noPrefix = many1 digit
                withPrefix = do char '#'
                                prefix <- oneOf "dox"
                                case prefix of
                                    'd' -> many1 digit
                                    'o' -> fmap (show . fst . head . readOct) (many1 octDigit)
                                    'x' -> fmap (show . fst . head . readHex) (many1 hexDigit)
    

    This should work