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 constrai
You cannot make Some c
an instance of Show
, except trivially.
You want to show
the a
inside Some
, but that variable is existentially quantified, so we cannot depend on any knowledge of the type of a
. In particular, we have no way of knowing that a
is an instance of Show
.
EDIT: I'll expand on my answer.
Even with more machinery, and giving up on a Show
instance, I still don't think what you want is possible because of the existential quantification.
First I'll rewrite Some
in a more familiar form
data Dict p where
Dict :: p a => a -> Dict p
The usual way to talk about "constraints implying constraints" is with the concept of constraint entailment.
data p :- q where
Sub :: p a => Dict q -> p :- q
We can think about a value of type p :- q
as a proof that if the constraint forall a. p a
holds, then forall a. q a
follows.
Now we try to write a sensible show
-ish function
showD :: p :- Show -> Dict p -> String
showD (Sub (Dict a)) (Dict b) = show b
At a glance, this might work. We have brought the following constraints into scope (forgive the pseudo-exists
syntax)
(0) p :: * -> Constraint
(1) exists a. p a -- (Dict p)
(2) exists b. p b => Show b -- (p :- Show)
But now things fall apart, GHC rightfully complains:
main.hs:10:33:
Could not deduce (Show a2) arising from a use of `show'
from the context (p a)
bound by a pattern with constructor
Sub :: forall (p :: * -> Constraint) (q :: * -> Constraint) a.
(p a) =>
Dict q -> p :- q,
in an equation for `showD'
at main.hs:10:8-19
or from (Show a1)
bound by a pattern with constructor
Dict :: forall (p :: * -> Constraint) a. (p a) => a -> Dict p,
in an equation for `showD'
at main.hs:10:13-18
or from (p a2)
bound by a pattern with constructor
Dict :: forall (p :: * -> Constraint) a. (p a) => a -> Dict p,
in an equation for `showD'
at main.hs:10:23-28
because it is impossible to unify the a
from (1)
with the b
from (2)
.
This is the same essential idea that is used throughout the constraints
package mentioned in the comments.