{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE InstanceSigs          #-}
{-# LANGUAGE PolyKinds             #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE StandaloneDeriving #-}
{- |

This module exposes internals of "Data.Type.Coercion.Sub".

Using this module allows to violate the premises 'Sub' type provides.
It is advisable not to import this module if there is another way,
and to limit the amount of code accesible to this module.

-}
module Data.Type.Coercion.Sub.Internal(
  Sub(..)
) where

import           Control.Category
import           Prelude                    hiding (id, (.))

import           Data.Coerce
import           Data.Type.Coercion

newtype Sub (a :: k) (b :: k) = Sub { Sub a b -> Coercion a b
getSub :: Coercion a b }
  deriving stock (Sub a b -> Sub a b -> Bool
(Sub a b -> Sub a b -> Bool)
-> (Sub a b -> Sub a b -> Bool) -> Eq (Sub a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
/= :: Sub a b -> Sub a b -> Bool
$c/= :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
== :: Sub a b -> Sub a b -> Bool
$c== :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
Eq, Eq (Sub a b)
Eq (Sub a b)
-> (Sub a b -> Sub a b -> Ordering)
-> (Sub a b -> Sub a b -> Bool)
-> (Sub a b -> Sub a b -> Bool)
-> (Sub a b -> Sub a b -> Bool)
-> (Sub a b -> Sub a b -> Bool)
-> (Sub a b -> Sub a b -> Sub a b)
-> (Sub a b -> Sub a b -> Sub a b)
-> Ord (Sub a b)
Sub a b -> Sub a b -> Bool
Sub a b -> Sub a b -> Ordering
Sub a b -> Sub a b -> Sub a b
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k (a :: k) (b :: k). Eq (Sub a b)
forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Ordering
forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Sub a b
min :: Sub a b -> Sub a b -> Sub a b
$cmin :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Sub a b
max :: Sub a b -> Sub a b -> Sub a b
$cmax :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Sub a b
>= :: Sub a b -> Sub a b -> Bool
$c>= :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
> :: Sub a b -> Sub a b -> Bool
$c> :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
<= :: Sub a b -> Sub a b -> Bool
$c<= :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
< :: Sub a b -> Sub a b -> Bool
$c< :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Bool
compare :: Sub a b -> Sub a b -> Ordering
$ccompare :: forall k (a :: k) (b :: k). Sub a b -> Sub a b -> Ordering
$cp1Ord :: forall k (a :: k) (b :: k). Eq (Sub a b)
Ord, Int -> Sub a b -> ShowS
[Sub a b] -> ShowS
Sub a b -> String
(Int -> Sub a b -> ShowS)
-> (Sub a b -> String) -> ([Sub a b] -> ShowS) -> Show (Sub a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (a :: k) (b :: k). Int -> Sub a b -> ShowS
forall k (a :: k) (b :: k). [Sub a b] -> ShowS
forall k (a :: k) (b :: k). Sub a b -> String
showList :: [Sub a b] -> ShowS
$cshowList :: forall k (a :: k) (b :: k). [Sub a b] -> ShowS
show :: Sub a b -> String
$cshow :: forall k (a :: k) (b :: k). Sub a b -> String
showsPrec :: Int -> Sub a b -> ShowS
$cshowsPrec :: forall k (a :: k) (b :: k). Int -> Sub a b -> ShowS
Show)
-- It is intentional to omit the 'TestCoercion' instance, existing for @Coercion@.
-- Knowing @Sub a b@ and @Sub a c@ should not conclude
-- @Coercible b c@.

deriving stock instance Coercible a b => Read (Sub a b)
deriving newtype instance Coercible a b => Enum (Sub a b)
deriving newtype instance Coercible a b => Bounded (Sub a b)

instance Category Sub where
  id :: Sub a a
  id :: Sub a a
id = Coercion a a -> Sub a a
forall k (a :: k) (b :: k). Coercion a b -> Sub a b
Sub Coercion a a
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

  (.) :: Sub b c -> Sub a b -> Sub a c
  Sub Coercion b c
Coercion . :: Sub b c -> Sub a b -> Sub a c
. Sub Coercion a b
Coercion = Coercion a c -> Sub a c
forall k (a :: k) (b :: k). Coercion a b -> Sub a b
Sub Coercion a c
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion