I'm playing around with the ConstraintKinds
extension of GHC.
I have the following data type, which is just a box for things fulfilling some one parameter constraint c
:
data Some (c :: * -> Constraint) where
Some :: forall a. c a => a -> Some c
For example, I could construct a box with some kind of number (arguably not very useful).
x :: Some Num
x = Some (1 :: Int)
Now, as long as c
includes the constraint Show
, I could provide an instance of Show (Some c)
.
instance ??? => Show (Some c) where
show (Some x) = show x -- Show dictionary for type of x should be in scope here
But how do I express this requirement in the instance context (marked with ???
)?
I cannot use an equality constraint (c ~ Show
), because the two are not necessarily equal. c
could be Num
, which implies, but is not equal to, Show
.
Edit
I realised that this cannot be possible in general.
If you have two values of type Some Eq
, it is not possible to compare them for equality. They could be of different types that each have their own notion of equality.
What applies to Eq
applies to any type class in which the type parameter appears on the right hand side of the first function arrow (like the second a
in (==) :: a -> a -> Bool
).
Considering that there is no way to create a constraint expressing "this type variable is not used beyond the first arrow", I don't think it is possible to write the instance I want to write.