dtlin's blog

instance Read a, given a Parsec parser

Submitted by dtlin on Fri, 10/07/2005 - 1:46pm.

Given any type a, for which there exists an parsecRead :: Parser a, the instance Read a can be defined really easily.
But I didn't find it in the Parsec docs.  Maybe I wasn't looking hard enough.

{- This code is dedicated to the public domain. -}
import Text.ParserCombinators.Parsec
class ParsecRead a where
  parsecRead :: Parser a
instance (ParsecRead a) => Read a where
  readsPrec _ = either (const []) id . parse parsecRead' "" where
    parsecRead' = do a <- parsecRead
                     rest <- getInput
                     return [(a, rest)]

It could be used like this:
data Foo = Foo
instance ParsecRead Foo where
  parsecRead = string "foo" >> return Foo
-- instance Read Foo

Defining instance Read a requires GHC's -fallow-undecidable-instances, though.
Well, you could always just repeat the readsPrec definition for everything you want, but it seems to me that this should exist just because it's convenient and common enough.