[GHC] #8924: Text.ParserCombinators.ReadP needs some kind of "commit" or "cut" to force a single parse..

GHC ghc-devs at haskell.org
Thu Jan 21 23:33:16 UTC 2016


#8924: Text.ParserCombinators.ReadP needs some kind of "commit" or "cut" to force
a single parse..
-------------------------------------+-------------------------------------
        Reporter:  PaulJohnson       |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Core Libraries    |              Version:  7.6.3
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by thomie):

 * cc: ekmett (added)
 * component:  Compiler => Core Libraries


@@ -5,0 +5,1 @@
+
@@ -8,1 +9,2 @@
- }}
+ }}}
+

New description:

 The ReadP monad maintains all possible parses of its input, rather than
 being left-biased as most parsers are. However this is not always quite
 the Right Thing. I maintain the Data.Decimal library. The Read instance
 for Data.Decimal up to 0.3.1 had the following behaviour:

 {{{
     reads "34.567e8 foo" :: [(Decimal, String)] = [(34.0,".567e8
 foo"),(34.567,"e8 foo"),(3.4567e9," foo")]
 }}}

 Clearly only the last parse in the list is the Right Thing, and any parser
 which returns "34.0" when given "34.567" is doing it wrong.

 The problem came from the implementation of "optional". In numbers only
 the integer part is mandatory, with the fractional and exponent parts
 being optional. So I wrote my parser with the fractional part parsed like
 this:
 {{{
           fractPart    <- optional "" $ do
                             _ <- char '.'
                             munch1 isDigit
 }}}
 The problem is that "optional" uses the symmetric choice operator (+++). I
 wrote this to work around the problem:
 {{{
     myOpt d p = p <++ return d
 }}}
 This uses the left-biased choice, so as soon as the parser sees the "." it
 commits to the fractional part.

 However this still isn't the Right Thing.
 {{{
     reads "34." :: [(Double, String)] = [(34.0, ".")]
 }}}
 but the parser above will fail to read it. Furthermore there are a number
 of combinators built on "+++" in ReadP, and it seems wrong to have left-
 biased variants of all of them.

 So what seems to be needed is some kind of "cut" operator, analogous to
 the Prolog "!" cut, which says that if you have got this far then you
 should commit to this parse and forget all the others. But it would have
 to be delimited because I only want that cut to apply to my Decimal type:
 if someone calls my Decimal parser then I don't want their parser to
 commit to an entire parse just because I have.

 So I think the feature I'm looking for is a delimited back-track akin to
 "prompt" in delimited continuations. But my monad-fu isn't good enough to
 design it.

--

Comment:

 > my monad-fu isn't good enough to design it.

 It's two year later, maybe your monad-fu is good enough to design it now?
 See [wiki:WorkingConventions/AddingFeatures] for how to submit a patch.

 Or maybe the CLC has something to say about this feature request?

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8924#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list