14

So I have a data type

data SomeType a =
    Type a |
    Mix (SomeType a) (SomeType a)

This my show instance for SomeType

instance (Show a) => Show (SomeType a) where
    show (Type a) = show a
    show (Mix a b) = "(" ++ show a ++ " " ++ show b ++ ")"

So

Mix (Type 5) (Type 4)

would give me

(5 4)

Now I want to have

read "(3 4)" :: SomeType Int 

produce

(3 4)

or

read "(a b)" :: SomeType Char

produce

(a b)

I am lost at how to use the Read class.

2
  • btw, your example for SomeType Char is not what show (Mix (Type 'a') (Type 'b')) would have generated. Commented Oct 21, 2011 at 15:45
  • 2
    You can derive both - the Show and Read instance - with a deriving (Show, Read) after the type delcaration. While they won't produce your output and input, they are a standard way of showing (and sometimes reading) values, which is why you should use them instead of your own instances. If you want to show them in a different way, use a separate function and call it render or so. Commented Oct 21, 2011 at 15:59

1 Answer 1

13

Here's an example based on the documentation which should be able to parse everything that show renders (assuming the type has a compatible Read instance defined), that is read . show should be more or less the identity:

instance (Read a) => Read (SomeType a) where
    readsPrec d r = readMix r ++ readType r
      where
        readMix = readParen True $ \r -> do
            (v1, r'') <- readsPrec d r
            (v2, r')  <- readsPrec d r''
            return (Mix v1 v2, r')

        readType r = do
            (v, r') <- readsPrec d r
            return (Type v, r')

Thus,

> read "(3 4)" :: SomeType Int 
(3 4)
it :: SomeType Int

But note, that for SomeType Char the default Show instance of Char surrounds the character with single quotes:

> read "('a' ('b' 'c'))" :: SomeType Char
('a' ('b' 'c'))
it :: SomeType Char

hope this helps

Sign up to request clarification or add additional context in comments.

1 Comment

@Qin d is the operator precedence (which I accidentally incremented -- I've edited this) of the enclosing parsing context and r is the current remaining string to be parsed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.