Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,248
    • Issues 4,248
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 391
    • Merge Requests 391
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #12358

Closed
Open
Opened Jul 02, 2016 by Ryan Scott@RyanGlScottMaintainer

Read1/Read2 don't have methods defined in terms of ReadPrec

Original Haskell libraries mailing list discussion: https://mail.haskell.org/pipermail/libraries/2016-June/027102.html

GHC 8.0 added the Data.Functor.Classes module to base, and with it the Read1 and Read2 typeclasses. The current definition of Read1 is this:

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 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:

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:

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 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.

Trac metadata
Trac field Value
Version 8.0.1
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Assignee
Assign to
8.2.1
Milestone
8.2.1 (Past due)
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#12358