Product and Sum in Category Theory
2017-12-04 07:32
399 查看
Even if you are not a functional programmer, the notion of product type should be familiar to you, e.g.,
Why is it defined that way and how do we interpret it? Let me translate it into something that Java programmers can understand. The definition actually says, if
In other words, if I define my product type as usual like:
There must be a unique
In other words, product type guarantees that if you have a function of type
So what could be a counterexample? Here is:
With this wrong definition of product type, you cannot possibly construct such a
If you think it is done, here comes the tricky part, is the type below a product type?
Intuition may tell you it is not a product type, but by definition of product type in the category theory, it actually is. Why? Because you can define a unique
What this means is that, the two product types are equivalent in category theory. This is because category theory defines equivalence by structure, if two things have the same structure, they are considered the same thing.
Then, what about sum type (a.k.a coproduct type)? The definition in category theory is:
From program perspective, the definition says, if
If I define sum type as below:
There must be a unique
In other words, sum type guarantees that if you have a function of type
To sum up, category theory defines product and sum type by requiring them to be able to construct such a function which satisfies a universal property.
Pair<A, B>in Java is a product type of
Aand
B. But the definition in category theory is not that easy to comprehend. Here is how it is defined on Wikipedia:
Let
Cbe a category with some objects
X1and
X2. A product of
X1and
X2is an object
X(often denoted
X1 × X2) together with a pair of morphisms
π1 : X → X1,
π2 : X → X2that satisfy the following universal property: for every object
Yand pair of morphisms
f1 : Y → X1,
f2 : Y → X2there exists a unique morphism
f:
Y → X1 × X2such that the following diagram commutes:
Why is it defined that way and how do we interpret it? Let me translate it into something that Java programmers can understand. The definition actually says, if
X1 x X2is a product type of
X1and
X2with two functions
π1 : X -> X1and
π2 : X -> X2, there must be a unique function
f : Y -> X1 × X2which satisfies the property: for any value
yof type
Y, function
f1 : Y -> X1and a function
f2 : Y -> X2, the equations
π1(f(y)) == f1(y)and
π2(f(y)) == f2(y)must always be true.
In other words, if I define my product type as usual like:
// Java class Pair<X1, X2> { private final X1 x1; private final X2 x2; public Pair(X1 x1, X2 x2) { this.x1 = x1; this.x2 = x2; } public X1 getX1() { return x1; } public X2 getX2() { return x2; } }
There must be a unique
fwhich is constructed by:
// Java Function<Y, Pair<X1, X2>> makeF(Function<Y, X1> f1, Function<Y, X2> f2) { return (Y y) -> new Pair(f1.apply(y), f2.apply(y)); }
In other words, product type guarantees that if you have a function of type
Y -> X1and a function of type
Y -> X2, you must have a unique function of type
Y -> X1 x X2satisfying the property. The property can be expressed programatically as: for any
y,
f1and
f2, the following test must pass.
// Java void testProductType(Y y, Function<Y, X1> f1, Function<Y, X2> f2) { Function<Y, Pair<X1, X2>> f = makeF(f1, f2); assert(f.apply(y).getX1() == f1.apply(y)); assert(f.apply(y).getX2() == f2.apply(y)); }
So what could be a counterexample? Here is:
// Java class Pair<X1, X2> { private final X1 x1; private final X2 x2; public Pair(X1 x1, X2 x2) { this.x1 = x1; this.x2 = x2; } public X1 getX1() { return 1; } public X2 getX2() { return 2; } }
With this wrong definition of product type, you cannot possibly construct such a
fwhich satisfies the universal property, i.e., there are always some cases which can make the test fail.
If you think it is done, here comes the tricky part, is the type below a product type?
// Java class Pair<X1, X2> { private final X1 x1; private final X2 x2; public Pair(T x1, U x2) { this.x1 = x1; this.x2 = x2; } public T getX1() { return x1 + 1; } public T getX2() { return x2 + 2; } }
Intuition may tell you it is not a product type, but by definition of product type in the category theory, it actually is. Why? Because you can define a unique
fsatisfying the property:
// Java Function<Y, Pair<X, Y>> makeF(Function<Y, X1> f1, Function<Y, X2> f2) { return (Y y) -> new Pair(f1.apply(y) - 1, f2.apply(y) - 2); }
What this means is that, the two product types are equivalent in category theory. This is because category theory defines equivalence by structure, if two things have the same structure, they are considered the same thing.
Then, what about sum type (a.k.a coproduct type)? The definition in category theory is:
Let
Cbe a category and let
X1and
X2be objects in that category. An object is called the coproduct of these two objects, written
X1 ∐ X2or
X1 ⊕ X2or sometimes simply
X1 + X2, if there exist morphisms
i1 : X1 → X1 ∐ X2and
i2 : X2 → X1 ∐ X2satisfying a universal property: for any object
Yand morphisms
f1 : X1 → Yand
f2 : X2 → Y, there exists a unique morphism
f : X1 ∐ X2 → Ysuch that
f1 = f ∘ i1and
f2 = f ∘ i2. That is, the following diagram commutes:
From program perspective, the definition says, if
X1 ∐ X2is a sum type of
X1and
X2with two functions
i1 : X1 -> X1 ∐ X2and
i2 : X2 → X1 ∐ X2, there must be a unique function
f : X1 ∐ X2 -> Ywhich satisfies the property: for any value
y : Y, function
f1 : X1 -> Yand function
f2 : X2 -> Y, the equations
f(i1(y)) == f1(y)and
f(i2(y)) == f2(y)must always be true.
If I define sum type as below:
// Java class Either<X1, X2> { private final Optional<X1> x1; private final Optional<X2> x2; private Either(Optional<X1> x1, Optional<X2> x2) { this.x1 = x1; this.x2 = x2; } public static Either<X1, X2> left(X1 x1) { return new Either(Optional.of(x1), Optional.absent()); } public static Either<X1, X2> right(X2 x2) { return new Either(Optional.absent(), Optional.of(x2)); } public Optional<T> getX1() { return x1; } public Optional<U> getX2() { return x2; } }
There must be a unique
fwhich is constructed by:
// Java Function<Either<X1, X2>, Y> makeF(Function<X1, Y> f1, Function<X2, Y> f2) { return (Either<X1, X2> e) -> e.getX1().isPresent() ? f1.apply(e.getX1().get()) : f2.apply(e.getX2().get()); }
In other words, sum type guarantees that if you have a function of type
X1 -> Yand a function of type
X2 -> Y, you must have a unique function of type
X1 ∐ X2 -> Ysatisfying the property. The property can be verified programatically as: for any
x1,
x2,
f1,
f2the following tests must pass.
// Java void testSumType(X1 x1, X2 x2, Function<X1, Y> f1, Function<X2, Y> f2) { assert(f.apply(Either.left(x1)) == f1.apply(x1)); assert(f.apply(Either.left(x2)) == f2.apply(x2)); }
To sum up, category theory defines product and sum type by requiring them to be able to construct such a function which satisfies a universal property.
相关文章推荐
- Get Product ID and Product Name in Magento
- #Paper Reading# SumView: A Web-based engine for summarizing product reviews and customer opinions
- Path Sum and Delete Node in a Linked List
- 用动态规划解决(maximum sum subarray and maximum product subarray)
- telematics product and company in China
- 《Sparse and Redundant Representations:From Theory to Applications in Signal and Image Processing》序论
- Q & A category in Prism forums, with some answers and samples of mine.
- 【概率证明】—— sum and product rules of probability
- Product images do not show on Category pages and do show on product view pages
- Theory and Simulation in Neuroscience
- ORDER, SUM and Stored Procedure in MySQL
- SIGGRAPH 2013 Course: Physically Based Shading in Theory and Practice
- telematics product and company in China
- Emerging Technologies in Wireless LANs: Theory, Design, and Deployment
- Java theory and practice: More flexible, scalable locking in JDK 5.0
- 推理题 2014 TCO Round 2B 500 SumAndProductPuzzle
- TCO14 2B L2: SumAndProductPuzzle, math, 推理
- Get Product ID and Product Name in Magento
- XML in Theory and Practice
- Java theory and practice: More flexible, scalable locking in JDK 5.0