{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DefaultSignatures #-}
module Data.Roles
  ( Representational(rep)
  , Phantom(phantom)
  ) where

import Control.Applicative
import Control.Monad.ST
import Data.Complex
import Data.Monoid
import Data.Proxy
import Data.Type.Coercion
import Data.Coerce
import Unsafe.Coerce
import Data.Map
import Data.IntMap

class Representational (t :: k1 -> k2) where
  -- | An argument is representational if you can lift a coercion of the argument into one of the whole
  rep :: Coercion a b -> Coercion (t a) (t b)
  default rep :: Phantom t => Coercion a b -> Coercion (t a) (t b)
  rep Coercion a b
_ = Coercion (t a) (t b)
forall k1 k2 (t :: k1 -> k2) (a :: k1) (b :: k1).
Phantom t =>
Coercion (t a) (t b)
phantom

class Representational t => Phantom (t :: k1 -> k2) where
  -- | An argument is phantom if you can 'coerce' the whole ignoring the argument
  phantom :: Coercion (t a) (t b)
  default phantom :: Coercible (t a) (t b) => Coercion (t a) (t b)
  phantom = Coercion (t a) (t b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

-- * Data.Proxy

instance Representational Proxy
instance Phantom Proxy

-- * Const

instance Representational Const where rep :: Coercion a b -> Coercion (Const a) (Const b)
rep Coercion a b
Coercion = Coercion (Const a) (Const b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational (Const a)
instance Phantom (Const a)

-- * Data.Type.Coercion

instance Representational Coercion     where rep :: Coercion a b -> Coercion (Coercion a) (Coercion b)
rep = Coercion a b -> Coercion (Coercion a) (Coercion b)
forall a b. a -> b
unsafeCoerce
instance Representational (Coercion a) where rep :: Coercion a b -> Coercion (Coercion a a) (Coercion a b)
rep Coercion a b
Coercion = Coercion (Coercion a a) (Coercion a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

-- * Prelude

instance Representational (->)       where rep :: Coercion a b -> Coercion ((->) a) ((->) b)
rep Coercion a b
Coercion = Coercion ((->) a) ((->) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((->) a)   where rep :: Coercion a b -> Coercion (a -> a) (a -> b)
rep Coercion a b
Coercion = Coercion (a -> a) (a -> b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational Either     where rep :: Coercion a b -> Coercion (Either a) (Either b)
rep Coercion a b
Coercion = Coercion (Either a) (Either b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational (Either a) where rep :: Coercion a b -> Coercion (Either a a) (Either a b)
rep Coercion a b
Coercion = Coercion (Either a a) (Either a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational (,)     where rep :: Coercion a b -> Coercion ((,) a) ((,) b)
rep Coercion a b
Coercion = Coercion ((,) a) ((,) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,) a) where rep :: Coercion a b -> Coercion (a, a) (a, b)
rep Coercion a b
Coercion = Coercion (a, a) (a, b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational (,,)       where rep :: Coercion a b -> Coercion ((,,) a) ((,,) b)
rep Coercion a b
Coercion = Coercion ((,,) a) ((,,) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,) a)   where rep :: Coercion a b -> Coercion ((,,) a a) ((,,) a b)
rep Coercion a b
Coercion = Coercion ((,,) a a) ((,,) a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,) a b) where rep :: Coercion a b -> Coercion (a, b, a) (a, b, b)
rep Coercion a b
Coercion = Coercion (a, b, a) (a, b, b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational (,,,)         where rep :: Coercion a b -> Coercion ((,,,) a) ((,,,) b)
rep Coercion a b
Coercion = Coercion ((,,,) a) ((,,,) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,) a)     where rep :: Coercion a b -> Coercion ((,,,) a a) ((,,,) a b)
rep Coercion a b
Coercion = Coercion ((,,,) a a) ((,,,) a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,) a b)   where rep :: Coercion a b -> Coercion ((,,,) a b a) ((,,,) a b b)
rep Coercion a b
Coercion = Coercion ((,,,) a b a) ((,,,) a b b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,) a b c) where rep :: Coercion a b -> Coercion (a, b, c, a) (a, b, c, b)
rep Coercion a b
Coercion = Coercion (a, b, c, a) (a, b, c, b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational (,,,,)           where rep :: Coercion a b -> Coercion ((,,,,) a) ((,,,,) b)
rep Coercion a b
Coercion = Coercion ((,,,,) a) ((,,,,) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,) a)       where rep :: Coercion a b -> Coercion ((,,,,) a a) ((,,,,) a b)
rep Coercion a b
Coercion = Coercion ((,,,,) a a) ((,,,,) a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,) a b)     where rep :: Coercion a b -> Coercion ((,,,,) a b a) ((,,,,) a b b)
rep Coercion a b
Coercion = Coercion ((,,,,) a b a) ((,,,,) a b b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,) a b c)   where rep :: Coercion a b -> Coercion ((,,,,) a b c a) ((,,,,) a b c b)
rep Coercion a b
Coercion = Coercion ((,,,,) a b c a) ((,,,,) a b c b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,) a b c d) where rep :: Coercion a b -> Coercion (a, b, c, d, a) (a, b, c, d, b)
rep Coercion a b
Coercion = Coercion (a, b, c, d, a) (a, b, c, d, b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational (,,,,,)             where rep :: Coercion a b -> Coercion ((,,,,,) a) ((,,,,,) b)
rep Coercion a b
Coercion = Coercion ((,,,,,) a) ((,,,,,) b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,,) a)         where rep :: Coercion a b -> Coercion ((,,,,,) a a) ((,,,,,) a b)
rep Coercion a b
Coercion = Coercion ((,,,,,) a a) ((,,,,,) a b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,,) a b)       where rep :: Coercion a b -> Coercion ((,,,,,) a b a) ((,,,,,) a b b)
rep Coercion a b
Coercion = Coercion ((,,,,,) a b a) ((,,,,,) a b b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,,) a b c)     where rep :: Coercion a b -> Coercion ((,,,,,) a b c a) ((,,,,,) a b c b)
rep Coercion a b
Coercion = Coercion ((,,,,,) a b c a) ((,,,,,) a b c b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,,) a b c d)   where rep :: Coercion a b -> Coercion ((,,,,,) a b c d a) ((,,,,,) a b c d b)
rep Coercion a b
Coercion = Coercion ((,,,,,) a b c d a) ((,,,,,) a b c d b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational ((,,,,,) a b c d e) where rep :: Coercion a b -> Coercion (a, b, c, d, e, a) (a, b, c, d, e, b)
rep Coercion a b
Coercion = Coercion (a, b, c, d, e, a) (a, b, c, d, e, b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

instance Representational []      where rep :: Coercion a b -> Coercion [a] [b]
rep Coercion a b
Coercion = Coercion [a] [b]
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational Maybe   where rep :: Coercion a b -> Coercion (Maybe a) (Maybe b)
rep Coercion a b
Coercion = Coercion (Maybe a) (Maybe b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational IO      where rep :: Coercion a b -> Coercion (IO a) (IO b)
rep Coercion a b
Coercion = Coercion (IO a) (IO b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational (ST s)  where rep :: Coercion a b -> Coercion (ST s a) (ST s b)
rep Coercion a b
Coercion = Coercion (ST s a) (ST s b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

-- * containers
instance Representational (Map k) where rep :: Coercion a b -> Coercion (Map k a) (Map k b)
rep Coercion a b
Coercion = Coercion (Map k a) (Map k b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational IntMap  where rep :: Coercion a b -> Coercion (IntMap a) (IntMap b)
rep Coercion a b
Coercion = Coercion (IntMap a) (IntMap b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

-- * Data.Complex

instance Representational Complex where rep :: Coercion a b -> Coercion (Complex a) (Complex b)
rep Coercion a b
Coercion = Coercion (Complex a) (Complex b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion

-- * Data.Monoid

instance Representational Sum     where rep :: Coercion a b -> Coercion (Sum a) (Sum b)
rep Coercion a b
Coercion = Coercion (Sum a) (Sum b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational Product where rep :: Coercion a b -> Coercion (Product a) (Product b)
rep Coercion a b
Coercion = Coercion (Product a) (Product b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational Dual    where rep :: Coercion a b -> Coercion (Dual a) (Dual b)
rep Coercion a b
Coercion = Coercion (Dual a) (Dual b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational Endo    where rep :: Coercion a b -> Coercion (Endo a) (Endo b)
rep Coercion a b
Coercion = Coercion (Endo a) (Endo b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational First   where rep :: Coercion a b -> Coercion (First a) (First b)
rep Coercion a b
Coercion = Coercion (First a) (First b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion
instance Representational Last    where rep :: Coercion a b -> Coercion (Last a) (Last b)
rep Coercion a b
Coercion = Coercion (Last a) (Last b)
forall k (a :: k) (b :: k). Coercible a b => Coercion a b
Coercion