[GHC] #12358: Read1/Read2 don't have methods defined in terms of ReadPrec
GHC
ghc-devs at haskell.org
Sat Jul 2 17:01:21 UTC 2016
#12358: Read1/Read2 don't have methods defined in terms of ReadPrec
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner:
Type: feature | Status: new
request |
Priority: normal | Milestone: 8.2.1
Component: | Version: 8.0.1
libraries/base |
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
Original Haskell libraries mailing list discussion:
https://mail.haskell.org/pipermail/libraries/2016-June/027102.html
> GHC 8.0 added the [http://hackage.haskell.org/package/base-4.9.0.0/docs
/Data-Functor-Classes.html Data.Functor.Classes] module to `base`, and
with it the `Read1` and `Read2` typeclasses. The current definition of
`Read1` is this:
>
> {{{#!hs
> class Read1 f where
> liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
> liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [f a]
> }}}
>
> There's a pretty big problem with this definition: it uses `ReadS` (a
synonym for `String -> [(a, String)]`). This sort of parser is very slow
(the docs even [http://hackage.haskell.org/package/base-4.9.0.0/docs/Text-
ParserCombinators-ReadP.html#t:ReadS admit as such]), and moreover, the
actual `Read` typeclass on which Read1 is based tries to avoid using it
whenever possible.
>
> The `Read` typeclass has this definition currently:
>
> {{{#!hs
> class Read a where
> readsPrec :: Int -> ReadS a
> readList :: ReadS [a]
> readPrec :: ReadPrec a
> readListPrec :: ReadPrec [a]
> }}}
>
> Where `ReadPrec` is a much more efficient parser datatype. When deriving
`Read` instances, GHC defines them in terms of `readPrec`, and gives the
other methods default definitions that leverage `readPrec`.
>
> For the sake of consistency, I propose adding analogous methods to
`Read1` and `Read2` that use the `ReadPrec` datatype. For example, here is
how I would change `Read1`:
>
> {{{#!hs
> class Read1 f where
> liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f
a)
> liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [f a]
> liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (f a)
> liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [f a]
> }}}
>
> And similarly for `Read2`. Here is a
[https://gist.github.com/RyanGlScott/7cdd11d6aa878e4229acf1a682beb1fc full
gist] with a sketch of what the new `Read1`/`Read2` definitions would look
like, including what the default definitions of the other methods would
be.
Diff coming soon.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12358>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list