See also SafeNewtypeDeriving
.
Haskell Wiki has an example of a non-parametric parameter of a type function:
type family Inspect x
type instance Inspect Age = Int
type instance Inspect Int = Bool
Here x
is non-parametric because to determine the outcome of applying Inspect
to a type argument, the type function must inspect x
.
In this case, the role of x
is nominal. We can declare the role explicitly with the RoleAnnotations
extension:
type role Inspect nominal
An example of a parametric parameter of a type function:
data List a = Nil | Cons a (List a)
type family DoNotInspect x
type instance DoNotInspect x = List x
Here x
is parametric because to determine the outcome of applying DoNotInspect
to a type argument, the type function do not need to inspect x
.
In this case, the role of x is representational. We can declare the role explicitly with the RoleAnnotations
extension:
type role DoNotInspect representational
A phantom type parameter has a phantom role. Phantom roles cannot be declared explicitly.