[Haskell-beginners] How to write Read instance

David McBride toad3k at gmail.com
Thu Nov 2 15:05:37 UTC 2017


My own toy example works.  I don't know how yours differs.

On Thu, Nov 2, 2017 at 10:51 AM, Baa <aquagnu at gmail.com> wrote:

> Hello, David!
>
> `Show` instance is simple:
>
>   instance Show Hex where
>     show = T.unpack . ghValue
>
> so
>
>   > show (Hex "1234ab")
>   1234ab
>   > read "1234ab"::Hex
>   1234ab
>   > read "Just 1234ab"::Maybe Hex -- fails like wrapped in the record!!
>
> Yes, I'm ignoring precedence usually too. And I return rest of the
> string. Playing with `UTCTime`'s readsPrec shows me that behaviour
> looks the same: UTCTime's reader returns the same rest. So, may be
> trick is in the:
>
> 1. Precedence ?!
> 2. readListPrec = readListPrecDefault
>    readList     = readListDefault   ?
>
>    But I get error: readListPrec is not visible method of class Read...
> 3. readPrec ? I implemented readsPrec which is old-style, but am I
>    right that old-style and new-style are absolutely the same from
>    reading point of view and old-style can replace new-style and vice
>    versa?
>
> PS. I don't import any special modules.
>
>
> > The most common way is to just auto derive Read.  I'm not sure that
> > that ever really fails.  Are you sure the problem isn't with the Show
> > instance of the type?  People commonly write invalid Show instances
> > to make them look pretty and they shouldn't.  read and show are
> > supposed to be inverses of each other because when they aren't,
> > problems like this occur.
> >
> > The simple way to do a Read instance is to implement the reads
> > function for it.  The confusion comes from its type.  readsPrec ::
> > Int -> ReadS a. ReadS is defined as String -> [(a, String)], where a
> > is the parsed result and String is the rest of the string that is
> > being parsed, , which may look confusing, and the Int is precedence,
> > which can usually be ignored.  It could have been Int -> String ->
> > Maybe (a, String), but Read predates Maybe.  So instead it returns a
> > list and if it fails to parse, it returns [] instead of Nothing.  So.
> >
> > data MyFoo = MyFoo
> >
> > instance Read MyFoo where
> >   -- readsPrec :: Int -> String -> [(MyFoo, String)]
> >   readsPrec _ = readFoo
> >
> > readFoo :: String -> [(MyFoo, String)]
> > readFoo str = case splitAt 5 str of
> >   ("MyFoo", rest) -> [(MyFoo, rest)]
> >   otherwise -> []
> >
> > If you need something more complex, there are functions to do it in
> > base that perform lexing and parsing.  I have never used them but you
> > can go ahead and read some of the instances such as Ordering at
> > https://hackage.haskell.org/package/base-4.10.0.0/docs/
> src/GHC.Read.html#line-398
> > to try and learn how it might work for you.
> >
> > But honestly I think you should look at fixing your Show instance
> > first, if possible.
> >
> >
> > On Thu, Nov 2, 2017 at 9:41 AM, Baa <aquagnu at gmail.com> wrote:
> >
> > > Hello all!
> > >
> > > I found some errors in the reading of previously shown big and
> > > complex record. Reason is: some of fields are reading wrongly. So,
> > > is there any useful documents how to write `Read` instance correctly
> > > (because I can't find good tutorial in the Web and often hit errors
> > > with `Read` instance)? May be tutorial/examples/any good info...
> > >
> > >
> > > ===
> > > Best regards, Paul
> > > _______________________________________________
> > > Beginners mailing list
> > > Beginners at haskell.org
> > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> > >
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20171102/13cb1774/attachment-0001.html>


More information about the Beginners mailing list