[Haskell-beginners] How to write Read instance
Baa
aquagnu at gmail.com
Thu Nov 2 15:13:43 UTC 2017
Does it work with wrapping in records, in "Just" ?
Would you show this example, please?
I try this:
import qualified Data.Text as T
import GHC.Read
import qualified Data.Char as C
newtype GitHash = GitHash { ghValue :: T.Text } deriving (Eq, Ord, Generic)
instance Show GitHash where
show = T.unpack . ghValue
instance Read GitHash where
readsPrec p = readParen (p > 10) reader where
reader :: ReadS GitHash
reader s =
case span C.isHexDigit s of
([], _) -> []
(hex, nohex) -> [(GitHash $ T.pack hex, nohex)]
readListPrec = readListPrecDefault
readList = readListDefault
and this parses:
> read "1234ab"::GitHash
but not this:
> read "Just 1234"::Maybe GitHash
*** Exception: Prelude.read: no parse
> 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
> >
More information about the Beginners
mailing list