Type signature of parser with existential quantification - parsing

In the beginning I had this simple type for a parser:
data Parser a = Parser ([Token] -> Either String (a, [Token]))
I use the Either for error messages on the left side and the parsed expression with the rest of the tokens on the right side.
This function "unpacks" the parser function.
parse :: Parser a -> [Token] -> Either String (a, [Token])
parse (Parser p) = p
My goal was to make the Parser more general that it does not only take tokens as input. So I used the ExistentialQuantification pragma and changed it to:
data Parser a = forall b. ([b] -> Either String (a, [b]))
What I want to know is: What type does the function "parse" have now?
I could not figure it out and it cannot be inferred. GHCi gave this error:
Couldn't match type `t' with `[b] -> Either String (t1, [b])'
`t' is a rigid type variable bound by
the inferred type of parse :: Parser t1 -> t
at ParserCombinator.hs:9:1
In the expression: p
In an equation for `parse': parse (Parser p) = p
Thanks for your help.
EDIT:
Thanks a lot for your answers.
The reason I wanted the type to look like "Parser a" because I had seen this in other parsing libraries for example in parsec.
But I saw now that this is just a shorthand for parsers that take strings as input.
It makes sense to use "data Parser b a" It was something I also tried earlier, but then I had a strange error in the monad instance for my parser, because I wrote data Parser a b instead:
import Control.Monad.Error
data Parser a b = Parser ([b] -> Either String (a, [b]))
parse (Parser p) = p
instance Monad (Parser x) where
p >>= f = Parser (\tokens -> do
(parsed, rest) <- parse p tokens
parse (f parsed) rest)
return a = Parser (\ts -> Right (a, ts))
fail b = Parser (\_ -> Left b)
It gives this error:
ParserCombinator.hs:12:18:
Couldn't match type `x' with `b'
`x' is a rigid type variable bound by
the instance declaration at ParserCombinator.hs:9:24
`b' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
Expected type: a
Actual type: x
In the first argument of `f', namely `parsed'
In the first argument of `parse', namely `(f parsed)'
In a stmt of a 'do' block: parse (f parsed) rest
ParserCombinator.hs:12:26:
Couldn't match type `a' with `b'
`a' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
`b' is a rigid type variable bound by
the type signature for
>>= :: Parser x a -> (a -> Parser x b) -> Parser x b
at ParserCombinator.hs:10:5
Expected type: [b]
Actual type: [a]
In the second argument of `parse', namely `rest'
In a stmt of a 'do' block: parse (f parsed) rest
ParserCombinator.hs:13:38:
Couldn't match type `a' with `x'
`a' is a rigid type variable bound by
the type signature for return :: a -> Parser x a
at ParserCombinator.hs:13:5
`x' is a rigid type variable bound by
the instance declaration at ParserCombinator.hs:9:24
In the expression: a
In the first argument of `Right', namely `(a, ts)'
In the expression: Right (a, ts)
Why does it work if you use Parser b a instead of Parser a b? And why do I need this x in Parser x? What does it contain?
It would be nice if you could give an example for another monad instance where this variable is used.

You mean
data Parser a = forall b. Parser ([b] -> Either String (a, [b]))
What this actually means becomes clearer if you write the existential in its more rigourous GADT notation:
data Parser a where
Parser :: forall b. ([b] -> Either String (a, [b])) -> Parser a
i.e. the constructor Parser is a universally-quantified function taking a ([b] -> ... parser, but returning always a Parser a that knows nothing about what specific b is to be used within. Therefore, this is basically useless: you can't supply a list of b token if you don't know what type that is actually supposed to be!
To make it concrete: parse would be the inverse of Parser; that swaps the quantors so it'd be an existential (duh) function
parse :: exists b . Parser a -> ([b] -> Either String (a, [b]))
Now, such a type doesn't exist in Haskell, but it's equivalent to having the arguments universal:
parse :: Parser a -> ((forall b . [b]) -> Either String (a, exists b . [b]))
At this point it's clear you can't use this in any meaningful way: the only inhabitants of forall b. [b] are [] and undefined (and, as Tikhon Jelvis remarks, [undefined], [undefined, undefined], [undefined, undefined, undefined] etc.).
I'm not sure what you actually intend to do with this type, but an existential is definitely not the right approach. Probably you should do
data Parser b a = Parser ([b] -> Either String (a, [b]))

Related

Taking a parser in argument and try to apply it zero or more times

I am currently writing a basic parser. A parser for type a takes a string in argument and returns either nothing, or an object of type a and the rest of the string.
Here is a simple type satisfying all these features:
type Parser a = String -> Maybe (a, String)
For example, I wrote a function that takes a Char as argument and returns a Parser Char :
parseChar :: Char -> Parser Char
parseChar _ [] = Nothing
parseChar c (x:xs)
| c == x = Just (x, xs)
| otherwise = Nothing
I would like to write a function which takes a parser in argument and tries to apply it zero or more times, returning a list of the parsed elements :
parse :: Parser a -> Parser [a]
Usage example:
> parse (parseChar ' ') " foobar"
Just (" ", "foobar")
I tried to write a recursive function but I can't save the parsed elements in a list.
How can I apply the parsing several times and save the result in a list ?
I tried to write a recursive function but I can't save the parsed elements in a list.
You don't need to "save" anything. You can use pattern matching. Here's a hint. Try to reason about what should happen in each case below. The middle case is a bit subtle, don't worry if you get that wrong at first. Note how s and s' are used below.
parse :: Parser a -> Parser [a]
parse p s = case p s of
Nothing -> ... -- first p failed
Just (x,s') -> case parse p s' of
Nothing -> ... -- subtle case, might not be relevant after all
Just (xs,s'') -> ... -- merge the results
Another hint: note that according to your description parse p should never fail, since it can always return the empty list.

Haskell Type error in Double recursion function

I'm trying to define a greedy function
greedy :: ReadP a -> ReadP [a]
that parses a sequence of values, returning only the "maximal" sequences that cannot be extended any further. For example,
> readP_to_S (greedy (string "a" +++ string "ab")) "abaac"
[(["a"],"baac"),(["ab","a","a"],"c")]
I'm using a very simple and probably clumsy way. Just parse the values and see if they can be parsed any further; if so, then reapply the function again to get all the possible values and concat that with the previous ones, or else just return the value itself. However, there seems to be some type problems, below is my code.
import Text.ParserCombinators.ReadP
addpair :: a -> [([a],String)] -> [([a],String)]
addpair a [] = []
addpair a (c:cs) = (a : (fst c), snd c ) : (addpair a cs)
greedy :: ReadP a -> ReadP [a]
greedy ap = readS_to_P (\s ->
let list = readP_to_S ap s in
f list )
where
f :: [(a,String)] -> [([a],String)]
f ((value, str2):cs) =
case readP_to_S ap str2 of
[] -> ([value], str2) : (f cs)
_ -> (addpair value (readP_to_S (greedy ap) str2)) ++ (f cs)
The GHC processes the code and says that function "f" has type [(a1,String)] -> [([a1],String)] but greedy is ReadP a -> ReadP [a]. I wonder why it is so because I think their type should agree. It also really helps if anyone can come up with some clever and more elegant approach to define the function greedy(my approach is definitely way too redundant)
To fix the compilation error, you need to add the language extension
{-# LANGUAGE ScopedTypeVariables #-}
to your source file, or pass the corresponding flag into the compiler. You also need to change the type signature of greedy to
greedy :: forall a. ReadP a -> ReadP [a]
This is because your two a type variables are not actually the same; they're in different scopes. With the extension and the forall, they are treated as being the same variable, and your types unify properly. Even then, the code errors, because you don't have an exhaustive pattern match in your definition of f. If you add
f [] = []
then the code seems to work as intended.
In order to simplify your code, I took a look at the provided function munch, which is defined as:
munch :: (Char -> Bool) -> ReadP String
-- ^ Parses the first zero or more characters satisfying the predicate.
-- Always succeeds, exactly once having consumed all the characters
-- Hence NOT the same as (many (satisfy p))
munch p =
do s <- look
scan s
where
scan (c:cs) | p c = do _ <- get; s <- scan cs; return (c:s)
scan _ = do return ""
In that spirit, your code can be rewritten as:
greedy2 :: forall a. ReadP a -> ReadP [a]
greedy2 ap = do
-- look at the string
s <- look
-- try parsing it, but without do notation
case readP_to_S ap s of
-- if we failed, then return nothing
[] -> return []
-- if we parsed something, ignore it
(_:_) -> do
-- parse it again, but this time inside of the monad
x <- ap
-- recurse, greedily parsing again
xs <- greedy2 ap
-- and return the concatenated values
return (x:xs)
This does have the speed disadvantage of executing ap twice as often as needed; this may be too slow for your use case. I'm sure my code could be further rewritten to avoid that, but I'm not a ReadP expert.

how to debug ReadP parser?

I've written a simple parser using readP. it works, but I'm using it as a sort of validating parser, as input is manually written and sometimes deviates from norm. in order to correct the input, I'd like to know in which line my parser failed, so my question is:
how can I obtain a debugging message showing in which line of input my parser failed, like the ones shown in real world haskell (for Parsec)?
(I'm fairly new to haskell, btw.)
ReadP doesn't offer error-reporting capabilities. That's evident from the type of a ReadP parser:
newtype ReadP a = R (forall b . (a -> P b) -> P b)
data P a
= Get (Char -> P a)
| Look (String -> P a)
| Fail
| Result a (P a)
| Final [(a,String)] -- invariant: list is non-empty!
deriving Functor
You can see that the Fail constructor doesn't store any information.
You will need to use a different parser combinator library for that (or build your own).

Implement `Applicative Parser`'s Apply Function

From Brent Yorgey's 2013 Penn class, after getting help on defining a Functor Parser, I'm attempting to make an Applicative Parser:
--p1 <*> p2 represents the parser which first runs p1 (which will
--consume some input and produce a function), then passes the
--remaining input to p2 (which consumes more input and produces
--some value), then returns the result of applying the function to the
--value
Here's my attempt:
instance Applicative (Parser) where
pure x = Parser $ \_ -> Just (x, [])
(Parser f) <*> (Parser g) = case (\ys -> f ys) of Nothing -> Parser Nothing
Just (_, xs) -> Parser $ g xs
However, I'm getting compile-time errors on the apply (<*>) definition.
Intuitively, I believe that using <*> achieves AND functionality.
If I have a parser for foo and a parser for bar, then I should be able to use apply <*> to say: foo followed by bar. In other words, input of foobar should successfully match, whereas foobip would not. It would fail on the second parser.
However, I believe that the types are:
Parser (a -> b) -> Parser a -> Parser b
So, that makes me think that my intuition is not entirely correct.
Please give me a tip to guide me towards understanding how to implement apply.
Your code is predicated on a misunderstanding of what a Parser is. Don't worry, virtually everybody makes this mistake.
newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
Lets break down what this means.
String -> Maybe (a, String)
[1] [2] [3] [4]
[1]: I take a string and return Maybe (a, String)
[2]: I might not succeed in parsing the input into the desired datatype
[3]: The desired type I am parsing the String into
[4]: Remaining input after having consumed the amount of data required to parse a
Parser is a function of text input to Maybe a tuple of a value and the rest of the text. Parser is emphatically not a tuple, otherwise you wouldn't have a parser. Just data in a tuple.
I'm not going to tell you how to implement <*> and nobody else should either as it would deprive you of the experience.
However, I'll give you pure so you understand the basic pattern:
pure a = Parser (\s -> Just (a, s))
See? It's a function of s -> Maybe (a, s). I intentionally mimicked the type variables in my terms to make it more obvious.

Creating a parser combinator of type Parser a -> Parser b -> Parser (Either a b)

I want to parse some text in which certain fields have structure most of the time but occasionally (due to special casing, typos etc) this structure is missing.
E.g. Regular case is Cost: 5, but occasionally it will read Cost: 5m or Cost: 3 + 1 per ally, or some other random stuff.
In the case of the normal parser (p) not working, I'd like to fallback to a parser which just takes the whole line as a string.
To this end, I'd like to create a combinator of type Parser a -> Parser b -> Either a b. However, I cannot work out how to inspect the results of attempting to see if the first parser succeeds or not, without doing something like case parse p "" txt of ....
I can't see a build in combinator, but I'm sure there's some easy way to solve this that I'm missing
I think you want something like this
eitherParse :: Parser a -> Parser b -> Parser (Either a b)
eitherParse a b = fmap Left (try a) <|> fmap Right b
The try is just to ensure that if a consumes some input and then fails, you'll backtrack properly. Then you can just use the normal methods for running a parser to yield Either ParseError (Either a b)
Which is quite easy to transform into your Either a b
case parse p "" str of
Right (Left a) -> useA a
Right (Right b) -> useB b
Left err -> handleParserError err
Try this: (<|>) :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
As a rule you could use it this way:
try p <|> q

Resources