Category Theory In Scala Meetu Maltiar Principal Consultant Knoldus
May 14, 2015
Category Theory In Scala
Meetu MaltiarPrincipal Consultant
Knoldus
Agenda
Category Theory the basics
Category Theory in Scala
Code Examples
Category
Pierce defines Category as comprising of:
● A collection of objects
● A collection of arrows (often called morphisms)
● Operations assigning to each arrow f an object dom f, its
domain, and an object cod f, its codomain (f:A → B, where
dom f = A and cod f = B)
Category continued..
A composition operator assigning to each pair of arrows f and g with cod f
= dom g, a composite arrow g o f: dom f → cod g, satisfying the following
associative law:
for any arrows f:A → B, g:B → C and h:C → D
h o (g o f) = (h o g) o f
For each object A, an identity arrow idA: A → A satisfying the following
identity law:
for any arrow f:A → B, idB o f = f and f o idA = f
Category
Apples
Banana
Brinjal
Fruit
Vegetable
f: A → B
Category Composition
Apples
Banana
Brinjal
Fruit
Vegetable
Living
Non Living
g o f: A → C
Translating to Scala
We can define any function from a type A to type B as:
A => B here we have an example or morphism
For any function val foo: A => B = //Anything
We have type A as domain of function foo and type B as co-domain
of function foo
Scala Category Example
We can define composition of arrows or functions in Scala with following REPL example
scala> val f: Int => String = _.toStringf: Int => String = <function1>
scala> val g: String => Int = _.lengthg: String => Int = <function1>
scala> f compose gres3: String => String = <function1>
Scala category identity continued
Identity law is a special version of a composition. Let's define function and play them in REPL:
scala> val foo: Int => String = _.toStringfoo: Int => String = <function1>
scala> val idInt: Int => Int = identity(_: Int)idInt: Int => Int = <function1>
scala> val idString: String => String = identity(_: String)idString: String => String = <function1>
scala> idString compose foores4: Int => String = <function1>
scala> foo compose idIntres5: Int => String = <function1>
Category theory and PL
Do understanding Category Theory makes us understand PL's better?If we just do Enterprise software development and do not want to go beyond our comfort zone then answer is no.
Category Theory provides uniform model of set theory, algebra, logic and computation.
Many concepts of Category theory maps nicely to structures of PL.
Categorical reasoning helps us to reason about programs. Some basic structures in PL like product and sum types have their correspondences in Category Theory.
There is a strong correspondence between typed lambda calculus and cartesian closed categories
Properties of data type in CT
Consider the category of Products of elements. Take for example of cartesian products from the category of sets.
A cartesian product of two sets A and B is defined by
A X B = {(a, b) | a belongs to A and b belongs to B}
For example if A = {1, 2} and B = {A, B}
A X B = {(1, A), (1, B), (2, A), (2, B)}
So here we have tuples or Pairs as objects in a Category
Properties of data type in CT ..
But what will be morphisms?
In case of products, the applicable arrows (or morphisms)
are the projection functions:
π1: A X B → A
π1: A X B → B
Properties of data type in CT ..
Now if we draw a Category diagram with C as a product type we
have two functions as projection functions:
1. f: C → A
2. g: C → B
and the product function is represented by: C → A X B It is defined
by:
<F, G>(x) = (f(x), g(x))
Diagram of CT
AXB BA
C
f g
[f,g]
π2π1
!
Diagram of CTFor every pair of vertices X and Y, all paths in the diagram from X
to Y are equal in the sense that each path forms an arrow and
these arrows are equal in category
For example the path from C to A is: <f,g> and π1 therefore
composition gives us:
π1 o <f,g> = f
Also path from C to B gives us: <f,g> and π2
π2 o <f,g> = g
Scala CT example
Lets now see how the laws of commutativity maps to Scala.
As a programmer we use the projection functions (_1 and _2) in Scala Tuple2 on a regular basis
In the CT diagram we will see that we get additional insights in abstraction and help understand mathematical properties of how cartesian product of sets map translates to composition of functions
Scala CT example...scala> val ip = (10, "meetu")ip: (Int, java.lang.String) = (10,meetu)
scala> val pi1: ((Int, String)) => Int = (p => p._1)pi1: ((Int, String)) => Int = <function1>
scala> val pi2: ((Int, String)) => String = (p => p._2)pi2: ((Int, String)) => String = <function1>
scala> val f: Int => Int = (_ * 2)f: Int => Int = <function1>
scala> val g: Int => String = _.toStringg: Int => String = <function1>
scala> val `<f, g>`: Int => (Int, String) = (x => (f(x), g(x))) <f, g>: Int => (Int, String) = <function1>
scala> pi1 compose `<f, g>`res0: Int => Int = <function1>
scala> pi2 compose `<f, g>`res1: Int => String = <function1>
Scala CT example
So we can claim from the commutativity of the diagram that:
pi1 compose `<f, g>` is type wise equal to f
pi2 compose `<f, g>` is type wise equal to g
Category theory says that morphism between C and A X B is unique and that A X B is defined upto isomorphism.
Uniqueness is denoted by ! In diagram. This makes sense as well because a pair can be unique
Interface driven modeling
Category Theory maps very closely to PL in the sense that it focuses on arrows rather than objects corresponding to Interfaces
Pierce: CT typically “abstracts away from elements, treating objects as black boxes with unimagined internal structure and focusing attention on the properties of arrows between objects”
Learning CT enriches both CT and PL. For example if we know what a Functor is in CT then we can easily make it generic enough so that it can interact with other Functors
Thinking Generically
CT talks about objects and morphisms and how arrows compose. A special kind of morphism is identity function in programming.
It is 0 in addition and 1 in multiplication
CT generalizes this concept by using same vocabulary (morphism) to denote both stuff that does some operations and those that don't
For every object X, there exists a morphism idX: X → X called identity morphism on X, such that for every morphism f: A → B we have:IdB o f = f = f o idA (used in monoids)
Duality
We have seen example of SumTypes for Product. If we look at the CT diagram of Sum compared to Product we see that arrows are reversed.
This is called a dual in CT. In Scala we model it by a Union Type like Either where value of SumType comes either from left or right
What's Next
FunctorsMonadsScalaz
Resources:1. Debasish Ghosh blog “Does Category Theory Makes you A Better Programmer”2. Heiko's blog on Category Theory3. Runar video on Scalaz