{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE TypeOperators #-}
module Data.Type.Role.Representational
( Representational
, Representation(..)
, applyRepresentational
, NonRepresentational
, NonRepresentation(..)
, innerNonRepresentational
) where
import Data.Coerce
import Data.Type.Coercion
import Data.Type.Equality ((:~:)(..))
import Data.Type.Role.Nominal
class (forall a b. Coercible a b => Coercible (f a) (f b))
=> Representational (f :: k -> l)
instance (forall a b. Coercible a b => Coercible (f a) (f b))
=> Representational f
data Representation (f :: k -> l) where
Representation :: Representational f => Representation f
applyRepresentational
:: Representation f -> Coercion f g -> Coercion a b -> Coercion (f a) (g b)
applyRepresentational Representation k@Coercion Coercion
= Coercion `trans` applyNominal k Refl
applyRepresentational'
:: Representation g -> Coercion f g -> Coercion a b -> Coercion (f a) (g b)
applyRepresentational' Representation k@Coercion Coercion
= applyNominal k Refl `trans` Coercion
class (forall a b. Coercible (f a) (f b) => a ~ b)
=> NonRepresentational (f :: k -> l)
instance (forall a b. Coercible (f a) (f b) => a ~ b)
=> NonRepresentational f
data NonRepresentation (f :: k -> l) where
NonRepresentation :: NonRepresentational f => NonRepresentation f
innerNonRepresentational
:: NonRepresentation f -> Coercion (f a) (f b) -> a :~: b
innerNonRepresentational NonRepresentation Coercion = Refl