| Safe Haskell | Safe |
|---|---|
| Language | Haskell2010 |
Overloaded.Categories
Description
Overloaded Categories, desugar Arrow into classes in this module.
Enabled with
{-# OPTIONS -fplugin=Overloaded -fplugin-opt=Overloaded:Categories #-}
Description
Arrows notation - GHC manual chapter -
is cool, but it desugars into "wrong" classes.
The arr combinator is used for plumbing. We should desugar to proper
type-classes:
CartesianCategory, notArrowCocartesianCategory, notArrowChoice(implementation relies onBicartesianCategory)CCC, notArrowApply(not implemented yet)
Examples
Expression like
catAssoc
:: CartesianCategory cat
=> cat (Product cat (Product cat a b) c) (Product cat a (Product cat b c))
catAssoc = proc ((x, y), z) -> identity -< (x, (y, z))
are desugared to (a mess which is)
fanout(proj1%%proj1) (fanout(proj2%%proj1)proj2)
If you are familiar with arrows-operators, this is similar to
(fst.fst)&&&(snd.fst&&&snd)
expression.
The catAssoc could be instantiated to cat = (->),
or more interestingly for example instantiate it to STLC morphisms to get an expression
like:
Lam (Pair (Fst (Fst (Var Here))) (Pair (Snd (Fst (Var Here))) (Snd (Var Here))))
proc notation is nicer than writing de Bruijn indices.
This is very similar idea to Conal Elliott's Compiling to Categories work. This approach is syntactically more heavy, but works in more correct stage of compiler, before actual desugarer.
As one more example, we implement the automatic differentiation, as in Conal's paper(s). To keep things simple we use
newtype AD a b = AD (a -> (b, a -> b))
representation, i.e. use ordinary maps to represent linear maps. We then define a function
evaluateAD :: Functor f => AD a b -> a -> f a -> (b, f b) evaluateAD (AD f) x xs = let (y, f') = f x in (y, fmap f' xs)
which would allow to calculuate function value and derivatives in given directions. Then we can define simple quadratic function:
quad :: AD (Double, Double) Double
quad = proc (x, y) -> do
x2 <- mult -< (x, x)
y2 <- mult -< (y, y)
plus -< (x2, y2)
It's not as simple as writing quad x y = x * x + y * y,
but not too far.
Then we can play with it. At origo everything is zero:
let sqrthf = 1 / sqrt 2 in evaluateAD quad (0, 0) [(1,0), (0,1), (sqrthf, sqrthf)] = (0.0,[0.0,0.0,0.0])
If we evaluate at some other point, we see things working:
evaluateAD quad (1, 2) [(1,0), (0,1), (sqrthf, sqrthf)] = (5.0,[2.0,4.0,4.242640687119285])
Obviously, if we would use inspectable representation for linear maps,
as Conal describe, we'd get more benefits. And then arr wouldn't
be definable!
Synopsis
- class Category (cat :: k -> k -> Type)
- identity :: Category cat => cat a a
- (%%) :: Category cat => cat b c -> cat a b -> cat a c
- class Category cat => CategoryWith1 (cat :: k -> k -> Type) where
- class CategoryWith1 cat => CartesianCategory (cat :: k -> k -> Type) where
- class Category cat => CocartesianCategory (cat :: k -> k -> Type) where
- class (CartesianCategory cat, CocartesianCategory cat) => BicartesianCategory cat where
- class CartesianCategory cat => CCC (cat :: k -> k -> Type) where
- type Exponential cat :: k -> k -> k
- eval :: cat (Product cat (Exponential cat a b) a) b
- transpose :: cat (Product cat a b) c -> cat a (Exponential cat b c)
- class Category cat => GeneralizedElement (cat :: k -> k -> Type) where
Documentation
class Category (cat :: k -> k -> Type) #
A class for categories. Instances should satisfy the laws
f.id= f -- (right identity)id.f = f -- (left identity) f.(g.h) = (f.g).h -- (associativity)
Instances
| Category (Coercion :: k -> k -> Type) | Since: base-4.7.0.0 |
| Category ((:~:) :: k -> k -> Type) | Since: base-4.7.0.0 |
| Category ((:~~:) :: k -> k -> Type) | Since: base-4.10.0.0 |
| (Category p, Category q) => Category (Product p q :: k -> k -> Type) | |
| (Applicative f, Category p) => Category (Tannen f p :: k -> k -> Type) | |
| (Applicative f, Monad f) => Category (WhenMissing f :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.IntMap.Internal Methods id :: WhenMissing f a a # (.) :: WhenMissing f b c -> WhenMissing f a b -> WhenMissing f a c # | |
| Category ((->) :: Type -> Type -> Type) | Since: base-3.0 |
Defined in Control.Category | |
| (Monad f, Applicative f) => Category (WhenMatched f x :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.IntMap.Internal Methods id :: WhenMatched f x a a # (.) :: WhenMatched f x b c -> WhenMatched f x a b -> WhenMatched f x a c # | |
| (Applicative f, Monad f) => Category (WhenMissing f k :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.Map.Internal Methods id :: WhenMissing f k a a # (.) :: WhenMissing f k b c -> WhenMissing f k a b -> WhenMissing f k a c # | |
| (Monad f, Applicative f) => Category (WhenMatched f k x :: Type -> Type -> Type) | Since: containers-0.5.9 |
Defined in Data.Map.Internal Methods id :: WhenMatched f k x a a # (.) :: WhenMatched f k x b c -> WhenMatched f k x a b -> WhenMatched f k x a c # | |
class Category cat => CategoryWith1 (cat :: k -> k -> Type) where Source #
Category with terminal object.
class CategoryWith1 cat => CartesianCategory (cat :: k -> k -> Type) where Source #
Cartesian category is a monoidal category where monoidal product is the categorical product.
Methods
proj1 :: cat (Product cat a b) a Source #
proj2 :: cat (Product cat a b) b Source #
fanout :: cat a b -> cat a c -> cat a (Product cat b c) Source #
is written as \(\langle f, g \rangle\) in category theory literature.fanout f g
class Category cat => CocartesianCategory (cat :: k -> k -> Type) where Source #
Cocartesian category is a monoidal category where monoidal product is the categorical coproduct.
Methods
inl :: cat a (Coproduct cat a b) Source #
inr :: cat b (Coproduct cat a b) Source #
fanin :: cat a c -> cat b c -> cat (Coproduct cat a b) c Source #
is written as \([f, g]\) in category theory literature.fanin f g
class (CartesianCategory cat, CocartesianCategory cat) => BicartesianCategory cat where Source #
Bicartesian category is category which is both cartesian and cocartesian.
We also require distributive morpism.
class CartesianCategory cat => CCC (cat :: k -> k -> Type) where Source #
Closed cartesian category.
Associated Types
type Exponential cat :: k -> k -> k Source #
represents \(B^A\). This is due how (->) works.Exponential cat a b
Methods
eval :: cat (Product cat (Exponential cat a b) a) b Source #
transpose :: cat (Product cat a b) c -> cat a (Exponential cat b c) Source #
Instances
| CCC ((->) :: Type -> Type -> Type) Source # | |
Defined in Overloaded.Categories Associated Types type Exponential (->) :: k -> k -> k Source # Methods eval :: Product (->) (Exponential (->) a b) a -> b Source # transpose :: (Product (->) a b -> c) -> a -> Exponential (->) b c Source # | |
class Category cat => GeneralizedElement (cat :: k -> k -> Type) where Source #