Search code examples
haskelltypespolymorphismparametric-polymorphismtype-signature

Right type signature for type parameter in Haskell


I have got two data types and want to write a class that returns the data from those data types:

data D1 a = Da1 a | Db1 a 
data D2 a = Da2 a | Db2 a 

class D a where
    extract :: ??? a -> a

instance D (D1 a) where
    extract (Da1 a) = a
    extract (Db1 a) = a

instance D (D2 a) where
    extract (Da2 a) = a
    extract (Db2 a) = a

If I had only one type D1 or D2 I could name it in the type signature, but what do I do in such a case where there are multiple possibilities? Is this even possible?


Solution

  • You need to make D1 and D2 instances of D instead of D1 a and D2 a. Then you can quantify extract over a and make extract return the a out of a D for all a.

    Since that probably wasn't very clear (sorry):

    class D d where
        -- `d` is the type constructor that's an instance of `D` (i.e. `D1` or
        -- `D2`) and `a` is a new type variable that can be any possible type
        extract :: d a -> a
    
    instance D D1 where
        extract (Da1 a) = a
        extract (Db1 a) = a