When can there be an ambiguous parse using reads? - parsing

The Standard Haskell Classes page says the following about reads :: (Read a) => String -> [(a,String)]:
Normally, a parser returns a singleton list, containing a value of
type a that was read from the input string and the remaining string
that follows what was parsed. If no parse was possible, however, the
result is the empty list, and if there is more than one possible parse
(an ambiguity), the resulting list contains more than one pair.
Under what situations or examples does this ambiguity manifest?

import Text.Read
data Foo = Bar Int | Baz Double deriving Show
instance Read Foo where
readPrec = fmap Bar readPrec +++ fmap Baz readPrec
In this example, the parser tries to parse Int and Double. If it can be parsed for both, the parser returns two values.
Resulting in:
> read "4" :: Foo
*** Exception: Prelude.read: ambiguous parse
and
> reads "4" :: [(Foo,String)]
[(Bar 4,""),(Baz 4.0,"")]
The easiest way here to fix ambiguity is to select one parse by replacing the choice operator +++ with the selective choice <++.

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.

Unpacking nested applicative functors f#

Hi I am attempting to make a combinator parser and I am currently attempting to make it read headers and create parsers based upon what the header which is parsed is. I.e A header of; int, float, string will result in Parser<Parser<int>*Parser<float>*Parser<string>>.
I am wondering however how you would unpack the "inner" parsers which and then end up with a something like; Parser<int*float*string>?
Parser type is: type Parser<'a> = Parser of (string -> Result<'a * string, string>)
I'm not sure that your idea with nested parsers is going to work - if you parse a header dynamically, then you'll need to produce a list of parsers of the same type. The way you wrote this is suggesting that the type of the parser will depend on the input, which is not possible in F#.
So, I'd expect that you will need to define a value like this:
type Value = Int of int | String of string | Float of float
And then your parser that parses a header will produce something like:
let parseHeaders args : Parser<Parser<Value> list> = (...)
The next question is, what do you want to do with the nested parsers? Presumably, you'll need to turn them into a single parser that parses the whole line of data (if this is something like a CSV file). Typically, you'd define a function sequence:
val sequence : sep:Parser<unit> -> parsers:Parser<'a> list -> Parser<'a list>
This takes a separator (say, parser to recognize a comma) and a list of parsers and produces a single parser that runs all the parsers in a sequence with the separator in between.
Then you can do:
parseHeaders input |> map (fun parsers -> sequence (char ',') parsers)
And you get a single parser Parser<Parser<string>>. You now want to run the nested parser on the rest of the that is left after running the outer parser, which recognizes headers. The following function does the trick:
let unwrap (Parser f:Parser<Parser<'a>>) = Parser (fun s ->
match f s with
| Result.Ok(Parser nested, rest) -> nested rest
| Result.Error e -> Result.Error e )

Idris parser combinator GADT

I am currently working on implementing a simple parser combinator library in Idris to learn the language and better understand type systems in general, but am having some trouble wrapping my head around how GADTs are declared and used. The parser data type that I am trying to formulate looks like (in Haskell): type Parser a = String -> [(a,String)], from this paper. Basically, the type is a function that takes a string and returns a list.
In Idris I have:
data Parser : Type -> Type where
fail : a -> (String -> [])
pass : a -> (String -> [(a,String)])
where the fail instance is a parser that always fails (i.e.- will be a function that always returns the empty list) and the pass instance is a parser that consumed some symbol. When loading the above into the interpreter, I get an error that there is a type mismatch between List elem and the expected type Type. But when I check the returned type of the parser in the repl with :t String -> List Type I get Type, which looks like it should work.
I would be very grateful if anyone could give a good explanation of why this data declaration does not work, or a better alternative to representing the parser data type.
In Haskell,
type Parser a = String -> [(a,String)]
doesn't create a new type, it is merely a type synonym. You can do something similar in Idris as
Parser : Type -> Type
Parser a = String -> List (a, String)
and then define your helper definitions as simple functions that return Parser as:
fail : Parser a
fail = const []
pass : a -> Parser a
pass x = \s => [(x, s)]
In defining your datatype Parser, the first line is saying this type takes a type and returns a type, in this case it takes an a and returns a Parser a.
So, your constructors should return Parser a.
Similar to a List which takes an a and returns a List a.
What you are currently returning in your constructors are not of type Parser - easily seen as nowhere does the word Parser occur on the right hand side.
Beyond that though, I'm not sure how you would best represent this.
However, there are some parser libraries already written in Idris, looking at these might help ? For example, have a look at this list of libraries, parsers are the first ones mentioned :-
Idris libraries

Using Parsec to write a Read instance

Using Parsec, I'm able to write a function of type String -> Maybe MyType with relative ease. I would now like to create a Read instance for my type based on that; however, I don't understand how readsPrec works or what it is supposed to do.
My best guess right now is that readsPrec is used to build a recursive parser from scratch to traverse a string, building up the desired datatype in Haskell. However, I already have a very robust parser who does that very thing for me. So how do I tell readsPrec to use my parser? What is the "operator precedence" parameter it takes, and what is it good for in my context?
If it helps, I've created a minimal example on Github. It contains a type, a parser, and a blank Read instance, and reflects quite well where I'm stuck.
(Background: The real parser is for Scheme.)
However, I already have a very robust parser who does that very thing for me.
It's actually not that robust, your parser has problems with superfluous parentheses, it won't parse
((1) (2))
for example, and it will throw an exception on some malformed inputs, because
singleP = Single . read <$> many digit
may use read "" :: Int.
That out of the way, the precedence argument is used to determine whether parentheses are necessary in some place, e.g. if you have
infixr 6 :+:
data a :+: b = a :+: b
data C = C Int
data D = D C
you don't need parentheses around a C 12 as an argument of (:+:), since the precedence of application is higher than that of (:+:), but you'd need parentheses around C 12 as an argument of D.
So you'd usually have something like
readsPrec p = needsParens (p >= precedenceLevel) someParser
where someParser parses a value from the input without enclosing parentheses, and needsParens True thing parses a thing between parentheses, while needsParens False thing parses a thing optionally enclosed in parentheses [you should always accept more parentheses than necessary, ((((((1)))))) should parse fine as an Int].
Since the readsPrec p parsers are used to parse parts of the input as parts of the value when reading lists, tuples etc., they must return not only the parsed value, but also the remaining part of the input.
With that, a simple way to transform a parsec parser to a readsPrec parser would be
withRemaining :: Parser a -> Parser (a, String)
withRemaining p = (,) <$> p <*> getInput
parsecToReadsPrec :: Parser a -> Int -> ReadS a
parsecToReadsPrec parsecParser prec input
= case parse (withremaining $ needsParens (prec >= threshold) parsecParser) "" input of
Left _ -> []
Right result -> [result]
If you're using GHC, it may however be preferable to use a ReadPrec / ReadP parser (built using Text.ParserCombinators.ReadP[rec]) instead of a parsec parser and define readPrec instead of readsPrec.

Parsing user input with reads in Haskell

I am trying to parse user entered string like "A12", into a Haskell tuple, like ('A', 12).
Here's what I have tried:
import Data.Maybe
type Pos = (Char, Int)
parse :: String -> Maybe Pos
parse u = do
(c, rest) <- (listToMaybe.reads) u
(r, _) <- (listToMaybe.reads) rest
return $ (c, r)
But this always returns Nothing. Why does this happen, and what is the correct way to parse this string? Since this is fairly simple, I'd like to avoid using Parsec or a similar advanced parsing library.
EDIT (to clarify):
Sample Input and Output:
"A12" gives Just ('A', 12)
"J5" gives Just ('J', 5)
"A" gives Nothing
"2324" gives Nothing
read is usually the opposite of show and they both generally use Haskell syntax to represent the given values. This means that since the Haskell syntax for characters uses single quotes, show on a character will add single quotes around it, and read will expect the single quotes to be there.
In other words, your function expects syntax like 'A' 42, and indeed it works if you try that:
> parse "'A' 42"
Just ('A',42)
For your format, I would instead use pattern matching for the first character and then reads for the rest, e.g. something like this:
parse :: String -> Maybe Pos
parse [] = Nothing
parse (c:rest) = do
(r, _) <- listToMaybe $ reads rest
return (c, r)
Do you have to use do notation? If not, the following function suits your needs. It's not pretty, but it gets the job done.
parse :: String -> Maybe Pos
parse (x:xs) = Just (x,read xs::Int)
I'm not sure what you consider "failing" and thus worth of a Nothing

Resources