87 lines
2.5 KiB
Haskell
87 lines
2.5 KiB
Haskell
module Functor.Base where
|
|
import Relation
|
|
|
|
import Data.Functor.Const (Const (Const), getConst)
|
|
import Data.Functor.Identity (Identity (Identity), runIdentity)
|
|
import Data.Either (Either (Left, Right))
|
|
import Data.Kind (Constraint, Type)
|
|
import Data.Maybe (Maybe (Just, Nothing))
|
|
|
|
type Functor :: (j -> k) -> Constraint
|
|
class (Category (Cod f), Category (Dom f)) => Functor (f :: j -> k) where
|
|
type Cod f :: Relation k
|
|
type Dom f :: Relation j
|
|
map :: Dom f x y -> Cod f (f x) (f y)
|
|
|
|
type Endofunctor :: (k -> k) -> Constraint
|
|
type Endofunctor f = (Functor f, Cod f ~ Dom f)
|
|
|
|
-- This can't be placed in a separate Category.Functor file
|
|
-- because the Functor instances for built-in types require Nat.
|
|
-- | A natural transformation between functors.
|
|
type Nat :: (k -> k -> Type) -> (j -> j -> Type) -> (j -> k) -> (j -> k) -> Type
|
|
data Nat dest src f g = (Functor f, Functor g, Dom f ~ src, Dom g ~ src, Cod f ~ dest, Cod g ~ dest) => Nat { runNat :: !(forall a. Object src a -> dest (f a) (g a)) }
|
|
|
|
instance Reflexive (Nat dest src) where
|
|
idL (Nat _) = Nat map
|
|
idR (Nat _) = Nat map
|
|
|
|
instance Transitive (Nat dest src) where
|
|
Nat f . Nat g = Nat \x -> f x . g x
|
|
|
|
instance Functor Maybe where
|
|
type Cod Maybe = (->)
|
|
type Dom Maybe = (->)
|
|
map f = \case
|
|
Just x -> Just (f x)
|
|
Nothing -> Nothing
|
|
|
|
instance Functor (Either a) where
|
|
type Cod (Either a) = (->)
|
|
type Dom (Either a) = (->)
|
|
map f = \case
|
|
Left y -> Left y
|
|
Right x -> Right (f x)
|
|
|
|
instance Functor ((,) a) where
|
|
type Cod ((,) a) = (->)
|
|
type Dom ((,) a) = (->)
|
|
map f = \(x, y) -> (x, f y)
|
|
|
|
instance Functor ((->) a) where
|
|
type Cod ((->) a) = (->)
|
|
type Dom ((->) a) = (->)
|
|
map = (.)
|
|
|
|
instance Functor Either where
|
|
type Cod Either = Nat (->) (->)
|
|
type Dom Either = (->)
|
|
map g = Nat \_ -> \case
|
|
Left y -> Left (g y)
|
|
Right x -> Right x
|
|
|
|
instance Functor (,) where
|
|
type Cod (,) = Nat (->) (->)
|
|
type Dom (,) = (->)
|
|
map g = Nat \_ (y, x) -> (g y, x)
|
|
|
|
instance Functor (->) where
|
|
type Cod (->) = Nat (->) (->)
|
|
type Dom (->) = Opposite (->)
|
|
map (Opposite f) = Nat \_ g -> (g . f)
|
|
|
|
instance Functor Identity where
|
|
type Cod Identity = (->)
|
|
type Dom Identity = (->)
|
|
map f = Identity . f . runIdentity
|
|
|
|
instance Functor (Const a :: Type -> Type) where
|
|
type Cod (Const a) = (->)
|
|
type Dom (Const a) = (->)
|
|
map _ = Const . getConst
|
|
|
|
instance Functor (Const :: Type -> Type -> Type) where
|
|
type Cod Const = Nat (->) (->)
|
|
type Dom Const = (->)
|
|
map f = Nat \_ -> Const . f . getConst
|