FiniteCategories-0.1.0.0: src/Currying/Currying.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-| Module : FiniteCategories
Description : Currying a functor @(A x B) -> C@ yields a functor @A -> [B,C]@.
Copyright : Guillaume Sabbagh 2021
License : GPL-3
Maintainer : guillaumesabbagh@protonmail.com
Stability : experimental
Portability : portable
Currying a functor @(A x B) -> C@ yields a functor @A -> [B,C]@.
-}
module Currying.Currying
(
curryDiagram,
uncurryDiagram,
switchArg,
)
where
import FiniteCategory.FiniteCategory
import ProductCategory.ProductCategory
import FunctorCategory.FunctorCategory
import Diagram.Diagram
import Utils.AssociationList
-- | Curry a functor @D : A x B -> C@ into a functor @D' : A -> [B,C]@.
curryDiagram :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq m1, Eq o1,
FiniteCategory c2 m2 o2, Morphism m2 o2, Eq m2, Eq o2,
FiniteCategory c3 m3 o3, Morphism m3 o3) =>
Diagram (ProductCategory c1 m1 o1 c2 m2 o2) (ProductMorphism m1 o1 m2 o2) (ProductObject o1 o2) c3 m3 o3 -> Diagram c1 m1 o1 (FunctorCategory c2 m2 o2 c3 m3 o3) (NaturalTransformation c2 m2 o2 c3 m3 o3) (Diagram c2 m2 o2 c3 m3 o3)
curryDiagram diag = Diagram{
src = (firstCategory (src diag)),
tgt = FunctorCategory{ sourceCat = (secondCategory (src diag)), targetCat = (tgt diag)},
omap = [(a, diagFromA a) | a <- ob (firstCategory (src diag))],
mmap = [(f, natFromF f) | f <- arrows (firstCategory (src diag))]
}
where
diagFromA a = Diagram{
src = (secondCategory (src diag)),
tgt = (tgt diag),
omap = [ (b, (omap diag) !-! (ProductObject a b) ) | b <- ob (secondCategory (src diag))],
mmap = [ (g, (mmap diag) !-! (ProductMorphism (identity (firstCategory (src diag)) a) g) ) | g <- arrows (secondCategory (src diag))]
}
natFromF f = NaturalTransformation{
srcNT = (diagFromA (source f)),
tgtNT = (diagFromA (target f)),
component = (\b -> (mmap diag) !-! (ProductMorphism f (identity (secondCategory (src diag)) b)))
}
-- | Uncurry a functor @D : A -> [B,C]@ into a functor @D' : A x B -> C@.
uncurryDiagram :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq m1, Eq o1,
FiniteCategory c2 m2 o2, Morphism m2 o2, Eq m2, Eq o2,
FiniteCategory c3 m3 o3, Morphism m3 o3) =>
Diagram c1 m1 o1 (FunctorCategory c2 m2 o2 c3 m3 o3) (NaturalTransformation c2 m2 o2 c3 m3 o3) (Diagram c2 m2 o2 c3 m3 o3) -> Diagram (ProductCategory c1 m1 o1 c2 m2 o2) (ProductMorphism m1 o1 m2 o2) (ProductObject o1 o2) c3 m3 o3
uncurryDiagram diag = Diagram{ src = ProductCategory (src diag) (sourceCat.tgt $ diag),
tgt = (targetCat.tgt $ diag),
omap = [(ProductObject a b, (omap ((omap diag) !-! a)) !-! b ) | a <- (ob (src diag)), b <- (ob (sourceCat.tgt $ diag))],
mmap = [(ProductMorphism f g, ((mmap ((omap diag) !-! (target f))) !-! g) @ ((component ((mmap diag) !-! f)) (source g)) ) | f <- (arrows (src diag)), g <- (arrows (sourceCat.tgt $ diag))]
}
-- | Switches argument of a diagram @D : A x B -> C@ to create a diagram @D' : B x A -> C@.
switch :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq m1, Eq o1,
FiniteCategory c2 m2 o2, Morphism m2 o2, Eq m2, Eq o2,
FiniteCategory c3 m3 o3, Morphism m3 o3) =>
Diagram (ProductCategory c1 m1 o1 c2 m2 o2) (ProductMorphism m1 o1 m2 o2) (ProductObject o1 o2) c3 m3 o3 -> Diagram (ProductCategory c2 m2 o2 c1 m1 o1) (ProductMorphism m2 o2 m1 o1) (ProductObject o2 o1) c3 m3 o3
switch diag = Diagram {
src = (ProductCategory (secondCategory.src $ diag) (firstCategory.src $ diag)),
tgt = (tgt diag),
omap = [((ProductObject b a), (omap diag) !-! o) | o@(ProductObject a b) <- (ob.src $ diag)],
mmap = [((ProductMorphism b a), (mmap diag) !-! o) | o@(ProductMorphism a b) <- (arrows.src $ diag)]
}
-- | Switches argument of a curried diagram.
switchArg :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq m1, Eq o1,
FiniteCategory c2 m2 o2, Morphism m2 o2, Eq m2, Eq o2,
FiniteCategory c3 m3 o3, Morphism m3 o3) =>
Diagram c1 m1 o1 (FunctorCategory c2 m2 o2 c3 m3 o3) (NaturalTransformation c2 m2 o2 c3 m3 o3) (Diagram c2 m2 o2 c3 m3 o3) -> Diagram c2 m2 o2 (FunctorCategory c1 m1 o1 c3 m3 o3) (NaturalTransformation c1 m1 o1 c3 m3 o3) (Diagram c1 m1 o1 c3 m3 o3)
switchArg = curryDiagram.switch.uncurryDiagram