-- | -- Module : Data.Embedding -- Copyright : (c) Justus Sagemüller 2015 -- License : GPL v3 -- -- Maintainer : (@) jsag $ hvl.no -- Stability : experimental -- Portability : portable -- {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE DataKinds #-} module Data.Embedding where import qualified Prelude as Hask hiding(foldl) import qualified Control.Applicative as Hask import qualified Control.Monad as Hask import qualified Data.Foldable as Hask import Control.Category.Constrained.Prelude hiding ((^)) import Control.Arrow.Constrained data Isomorphism c a b = Isomorphism { forwardIso :: c a b , backwardIso :: c b a } infixr 0 $->$, $<-$ ($->$) :: (Function c, Object c a, Object c b) => Isomorphism c a b -> a -> b Isomorphism f _ $->$ x = f $ x ($<-$) :: (Function c, Object c b, Object c a) => Isomorphism c a b -> b -> a Isomorphism _ p $<-$ y = p $ y fromInversePair :: c a b -> c b a -> Isomorphism c a b fromInversePair = Isomorphism perfectInvert :: Isomorphism c a b -> Isomorphism c b a perfectInvert (Isomorphism f b) = Isomorphism b f instance (Category c) => Category (Isomorphism c) where type Object (Isomorphism c) a = Object c a id = Isomorphism id id Isomorphism e p . Isomorphism f q = Isomorphism (e.f) (q.p) instance (Cartesian c) => Cartesian (Isomorphism c) where type UnitObject (Isomorphism c) = UnitObject c type PairObjects (Isomorphism c) a b = PairObjects c a b swap = Isomorphism swap swap attachUnit = Isomorphism attachUnit detachUnit detachUnit = Isomorphism detachUnit attachUnit regroup = Isomorphism regroup regroup' regroup' = Isomorphism regroup' regroup instance (CoCartesian c) => CoCartesian (Isomorphism c) where type ZeroObject (Isomorphism c) = ZeroObject c type SumObjects (Isomorphism c) a b = SumObjects c a b coSwap = Isomorphism coSwap coSwap attachZero = Isomorphism attachZero detachZero detachZero = Isomorphism detachZero attachZero coRegroup = Isomorphism coRegroup coRegroup' coRegroup' = Isomorphism coRegroup' coRegroup maybeAsSum = Isomorphism maybeAsSum maybeFromSum maybeFromSum = Isomorphism maybeFromSum maybeAsSum boolAsSum = Isomorphism boolAsSum boolFromSum boolFromSum = Isomorphism boolFromSum boolAsSum instance (Morphism c) => Morphism (Isomorphism c) where Isomorphism e p *** Isomorphism f q = Isomorphism (e***f) (p***q) instance (MorphChoice c) => MorphChoice (Isomorphism c) where Isomorphism e p +++ Isomorphism f q = Isomorphism (e+++f) (p+++q) instance (Category c) => EnhancedCat c (Isomorphism c) where arr = forwardIso instance (Category c) => EnhancedCat (Embedding c) (Isomorphism c) where arr (Isomorphism f b) = Embedding f b -- | A pair of matching functions. The projection must be a left (but not necessarily right) -- inverse of the embedding, -- i.e. the cardinality of @a@ will have to be less or equal than the cardinality -- of @b@. data Embedding c a b = Embedding { embedding :: c a b , projection :: c b a } fromEmbedProject :: c a b -- ^ Injective embedding -> c b a -- ^ Surjective projection. Must be left inverse of embedding. -> Embedding c a b fromEmbedProject = Embedding infixr 0 $->, >-$ ($->) :: (Function c, Object c a, Object c b) => Embedding c a b -> a -> b Embedding f _ $-> x = f $ x (>-$) :: (Function c, Object c b, Object c a) => Embedding c a b -> b -> a Embedding _ p >-$ y = p $ y instance (Category c) => Category (Embedding c) where type Object (Embedding c) a = Object c a id = Embedding id id Embedding e p . Embedding f q = Embedding (e.f) (q.p) instance (Cartesian c) => Cartesian (Embedding c) where type UnitObject (Embedding c) = UnitObject c type PairObjects (Embedding c) a b = PairObjects c a b swap = Embedding swap swap attachUnit = Embedding attachUnit detachUnit detachUnit = Embedding detachUnit attachUnit regroup = Embedding regroup regroup' regroup' = Embedding regroup' regroup instance (CoCartesian c) => CoCartesian (Embedding c) where type ZeroObject (Embedding c) = ZeroObject c type SumObjects (Embedding c) a b = SumObjects c a b coSwap = Embedding coSwap coSwap attachZero = Embedding attachZero detachZero detachZero = Embedding detachZero attachZero coRegroup = Embedding coRegroup coRegroup' coRegroup' = Embedding coRegroup' coRegroup maybeAsSum = Embedding maybeAsSum maybeFromSum maybeFromSum = Embedding maybeFromSum maybeAsSum boolAsSum = Embedding boolAsSum boolFromSum boolFromSum = Embedding boolFromSum boolAsSum instance (Morphism c) => Morphism (Embedding c) where Embedding e p *** Embedding f q = Embedding (e***f) (p***q) instance (MorphChoice c) => MorphChoice (Embedding c) where Embedding e p +++ Embedding f q = Embedding (e+++f) (p+++q) instance (Category c) => EnhancedCat c (Embedding c) where arr = embedding