AlgebraicJulia / AlgebraicJulia/Catlab.jl
Functor types
- 主要言語
- Julia
- スター
- 724
- フォーク
- 73
- PR マージ指標
- 30日以内にマージされた PR はありません
説明
Why don't we create an abstract type Functor that has the API:
```julia
dom(F::Functor)::Theory
codom(F::Functor)::Theory
function (F::Functor)(x::Ob{:generator})
...
end
function (F::Functor)(f::Hom{:compose})
foldl(compose, map(x->F(x), f.args))
end
function (F::Functor)(f::Hom{:generator})
...
end
```
The idea being that the functor type creator just has to specify what happens on the generators of the theory and the term constructors. Then the `MonoidalFunctor <: AbstractFunctor` would have the following additional method definitions:
```julia
function (F::MonoidalFunctor)(x::Ob{:otimes})
foldl(otimes, map(F, x.args))
end
function (F::MonoidalFunctor)(f::Hom{:compose})
foldl(compose, map(F, f.args))
end
function (F::MonoidalFunctor)(f::Hom{:otimes})
foldl(otimes, map(F, f.args))
end
```
In this setting, in order to make a functor, you would just have to define a type `MyFunctor<:MonoidalFunctor` which supplies the action on the generators. We could supply a `PresentedMonoidalFunctor` which works like the current implementation by storing a dictionary mapping the generators to their images under the functor.
```julia
struct PresentedMonoidalFunctor{K,V} <: MonoidalFunctor
g::Dict{K,V}
end
function (F::PresentedMonoidalFunctor)(x::Ob{:generator})
F.g[x]
end
function (F::PresentedMonoidalFunctor)(f::Hom{:generator})
F.g[x]
end
```
I think we could simplify a lot of this code if we store the GATExprs with the
operation as a `Function` instead of a `Symbol`. The current implementation looks
like:
```julia
julia> X = Ob(FreeSymmetricMonoidalCategory, :X)
julia> dump(X)
Catlab.Theories.FreeSymmetricMonoidalCategory.Ob{:generator}
args: Array{Symbol}((1,))
1: Symbol X
type_args: Array{GATExpr}((0,))
```
Instead of storing `head(ex) == :otimes` we could store the function `otimes`, this would allow a single abstract functor type with the idea that the codomain category will support all the term constructors of the domain category so that you can implement arbitrary GAT functors:
```julia
function (F::Functor)(x)
foldl(head(x), map(F, x.args))
end
#you still need a base case for generators
Generator = Union{Ob{:generator}, Hom{:generator}}
function (F::Functor)(x::Generator)
F.g[x]
end
```
コントリビューションガイド
評価
この issue はまだ評価されていません。