Search code examples
haskelltypesconstraints

How to constrain a class instance


I'm trying to apply a type constraint to an instance of a class that has kind ->.

data Data1 = Data1 String

class Class1 m where
    c1f :: m -> m

instance Class1 Data1 where
    c1f (Data1 v) = Data1 v


data Data2 a = Data2 a

class Class2 m where
    c2f :: a -> m a

instance Class2 Data2 where
    c2f x = Data2 (c1f x)

I see this error message from the last line:

No instance for (Class1 a) arising from a use of ‘c1f’

How do I apply the type constraint (Data 2 must be instance of Class1)?


Solution

  • Are you looking to let each instance of Class2 pick its own constraint? If so, try this:

    {-# LANGUAGE ConstraintKinds, TypeFamilies #-}
    
    import Data.Kind
    
    data Data1 = Data1 String
    
    class Class1 m where
        c1f :: m -> m
    
    instance Class1 Data1 where
        c1f (Data1 v) = Data1 v
    
    
    data Data2 a = Data2 a
    
    class Class2 m where
        type C2c m :: Type -> Constraint
        c2f :: C2c m a => a -> m a
    
    instance Class2 Data2 where
        type C2c Data2 = Class1
        c2f x = Data2 (c1f x)