The documentation for GHC.Read describes readPrec only by:
Proposed replacement for readsPrec using new-style parsers (GHC only).
Other functions, types, etc. have no documentation at all. How do I use the supposedly more efficient parsing functionality in the intended way? Why is it more efficient?
The toy example I’d like to try out the new GHC approach is this:
data RoseTree a = RoseTree a [RoseTree a] deriving (Eq)
-- | A RoseTree is being displayed "label[children…]" for
-- | nonempty children and just "label" for a leaf (= tree with no children).
instance Show a => Show (RoseTree a) where
show (RoseTree label []) = show label
show (RoseTree label ts) = show label ++ show ts
-- | Parses outputs of `show` to a RoseTree.
instance Read a => Read (RoseTree a) where
readsPrec n str = do
(label, labelRemaining) <- readsPrec n str
let tsReads = readsPrec n labelRemaining
(ts, tsRemaining) <- ([], labelRemaining) : tsReads
return (RoseTree label ts, tsRemaining)
I wrote this several years back for my Bachelor’s thesis and to be honest, I don’t understand the Read instance anymore. The code includes the Show instance as Read morally requires Show and should be compatible with it.
ReadPrecis (slightly) further documented in Text.ParserCombinators.ReadPrec. It implements the usual parser classes (Applicative,Monad,Alternative), so you should be able to use it something like this:You may want to think how this should interact with precedence, then insert appropriate calls to
stepandprec. You might also choose to use<++over<|>; the former is generally more efficient but may commit to its first argument too soon and prevent certain things from parsing that otherwise ought to.