Home > OS >  readP in Haskell has output that doesn't match the intended input when using the string
readP in Haskell has output that doesn't match the intended input when using the string

Time:12-05

I am trying to write a simple parser in Haskell using readP and following some pre-made code examples I have found.

I use the following:

import Data.Char

import Text.ParserCombinators.ReadP
import Control.Applicative ((<|>))


type Parser a = ReadP a 

type ParseError = String  

space :: Parser Char
space = satisfy isSpace

spaces :: Parser String 
spaces = many space


space1 :: Parser String
space1 = many1 space

symbol :: String -> Parser String
symbol = token . string

schar :: Char -> Parser Char
schar = token . char

token :: Parser a -> Parser a
token combinator = spaces >> combinator

runParser = readP_to_S

e :: Parser Int

e = do t
       
t :: Parser Int
t = (do string "0"
        return 0)
    <|> 
    (do string "1" 
        return 1)

parseString input = runParser (e >> eof) input

However I get the following output:

ghci> parseString "1"
[((),"")]
ghci> parseString "0"
[((),"")]
ghci> parseString ""
[]

Whereas I would expect the following output

ghci> parseString "1"
[("1","")]
ghci> parseString "0"
[("0","")]
ghci> parseString ""
[]

How come that is? And is there a way to make it print these outputs instead?

CodePudding user response:

The new code is better, but there is still an issue here

parseString input = runParser (e >> eof) input
                            --^^^^^^^^^^--

Adding >> eof discards the result of e. To retain it, we can either use

parseString input = runParser (e <* eof) input

Or, with a more basic approach:

whole :: Parser Int
whole = do
   val <- e       -- save the value produced by e
   eof            -- ensure the end of the parsed string
   return val     -- return the saved value

parseString input = runParser whole input

In either case, we get:

> parseString "1"
[(1,"")]

Note that the first component of the pair in the list is 1, an Int. Indeed, it has the same type mentioned in the signature whole :: Parser Int.

  • Related