Polymorphic restriction

I have a far-fetched type:

{-# LANGUAGE DeriveFunctor #-} data T a = T a deriving (Functor) 

... and this type is an instance of some contrived class:

 class C t where toInt :: t -> Int instance C (T a) where toInt _ = 0 

How can I express in a function constraint that T a is an instance of some class for all a ?

For example, consider the following function:

 ft = toInt $ fmap Left t 

Intuitively, I expect the above function to work, since toInt works on toInt for all a , but I cannot express it in a type. This does not work:

 f :: (Functor t, C (ta)) => ta -> Int 

... because, using fmap , the type became Either ab . I cannot fix this using:

 f :: (Functor t, C (t (Either ab))) => ta -> Int 

... because b does not represent a universally quantified variable. I also can not say:

 f :: (Functor t, C (tx)) => ta -> Int 

... or use forall x to suggest that the restriction is valid for all x .

So my question is is there a way to say that a constraint is polymorphic in some of its type variables.

+7
source share
1 answer

Using the constraints package:

 {-# LANGUAGE FlexibleContexts, ConstraintKinds, DeriveFunctor, TypeOperators #-} import Data.Constraint import Data.Constraint.Forall data T a = T a deriving (Functor) class C t where toInt :: t -> Int instance C (T a) where toInt _ = 0 f :: ForallF CT => T a -> Int ft = (toInt $ fmap Left t) \\ (instF :: ForallF CT :- C (T (Either ab))) 
+6
source

All Articles