[Haskell-beginners] How to write Read instance
Baa
aquagnu at gmail.com
Thu Nov 2 14:51:06 UTC 2017
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
> >
More information about the Beginners
mailing list