Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create instance of Read for a datatype in haskell

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.

like image 383
nobody Avatar asked Oct 21 '11 14:10

nobody


People also ask

How do you create a data type in Haskell?

Making your own data type in HaskellNew data types are created via the data keyword. To create a Point data type, we need to provide a type constructor (the name of our type) and a data constructor (used to construct new instances of the type), followed by the types our type will contain.

What is an instance in Haskell?

An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.

What is read Haskell?

The read function in Haskell is very easy to use and handle, and it helps the developers to convert the string into desired type available in Haskell. Also its syntax is very much clear and only requires us to use the 'read' keyword and the string we want to parse.

What is a Typeclass in Haskell?

Type Classes are a language mechanism in Haskell designed to support general overloading in a principled way. They address each of the concerns raised above. They provide concise types to describe overloaded functions, so there is no expo- nential blow-up in the number of versions of an overloaded function.


1 Answers

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

like image 106
hvr Avatar answered Oct 15 '22 13:10

hvr