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 Text.ParserCombinators.ReadP
import Control.Applicative ((<|>))
t :: ReadP Int
t = (do string "0"
return 0)
<|>
(do string "1"
return 1)
parseString = readP_to_S (t >> eof)
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?
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
.