I would like to express a Constraint
on types of kind k -> k -> Type
, which can be stated in English as:
A type
s
such that, forallx
x'
,y
, andy'
whereCoercible x x'
andCoercible y y'
,Coercible (s x y) (s x' y')
Or in even plainer English:
A type
s
that is always coercible if its two parameters are coercible.
The latter seems tantalizingly close to haskell already, and I have some code that really looks like it should do it:
type Representational2 (s :: k -> k -> Type) =
forall x x' y y'. (Coercible x x', Coercible y y') => Coercible (s x y) (s x' y')
However this doesn't work, ghc wants Coercible (s x y) (s x' y')
to be a type but it is a Constraint
(ConstraintKinds
and QuantifiedConstraints
are on).
• Expected a type, but
‘Coercible (s x y) (s x' y')’ has kind
‘Constraint’
• In the type ‘forall x x' y y'.
(Coercible x x', Coercible y y') => Coercible (s x y) (s x' y')’
In the type declaration for ‘Representational2’
I don't fully understand what is going on but I gather that ghc does not like a Constraint
being on the right hand side of =>
within a type
. Since I can create type aliases with Constraint
kinds and I can create type
aliases with =>
, no problem.
What is the issue and how can I express this contraint to ghc in a manner it accepts?
To define a constraint, you first compute the value of interest using the decision variables. Then you place an appropriate limit (<=, = or >=) on this computed value. The following examples illustrate a variety of types of constraints that commonly occur in optimization problems.
A variable constraint is a bound put on the possible values of a variable in an equation, function, or application. These constraints use comparison symbols such as <, ≤, >, ≥, ≠, and = to specify which values of the variable are to be used in the given context.
This works:
{-# LANGUAGE ConstraintKinds, PolyKinds, RankNTypes, QuantifiedConstraints #-}
import Data.Kind
import Data.Coerce
type Representational2 (s :: k -> k -> Type) =
forall x x' y y'. (Coercible x x', Coercible y y') => Coercible (s x y) (s x' y') :: Constraint
All I did was add :: Constraint
to your type. Since GHC already knew the kind of the RHS was Constraint
(due to the error message), I don't really have a good explanation for why this makes it work.
Edit: I have a partial explanation: by adding that kind signature to the RHS, your type synonym now has a CUSK (see the GHC wiki):
- A type synonym has a CUSK if and only if all of its type variables and its RHS are annotated with kinds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With