{"id":3580,"date":"2018-10-14T15:58:27","date_gmt":"2018-10-14T19:58:27","guid":{"rendered":"http:\/\/www.goodmath.org\/blog\/?p=3580"},"modified":"2019-02-20T20:26:05","modified_gmt":"2019-02-21T01:26:05","slug":"another-stab-at-category-theory-starting-with-monoids","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2018\/10\/14\/another-stab-at-category-theory-starting-with-monoids\/","title":{"rendered":"Another Stab at Category Theory:  Lesson one: Starting with Monoids"},"content":{"rendered":"<h1>Introduction and Motivation<\/h1>\n<p>One thing that I keep bumping up against as an engineer who loves functional a programming is category theory. It often seems like there are two kinds of functional programmers: people who came into functional programming via engineering, and people who came into functional programming via math. The problem is that a lot of the really interesting work in languages and libraries for functional programming are being built from the mathematical side, but for people on the engineering side, it&#8217;s impenetrable: it&#8217;s like it&#8217;s written in a whole different language, and even basic discussions about programming go off the rails, because the basic abstractions don&#8217;t make any sense if you don&#8217;t know category theory.<\/p>\n<p>But how do you learn category theory? It seems impenetrable to mere humans. For example, one of the textbooks on category theory that several people told me was the most approachable starts chapter one with the line:<\/p>\n<blockquote><p>A group extension of an abelian group <img src='http:\/\/l.wordpress.com\/latex.php?latex=H&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='H' style='vertical-align:1%' class='tex' alt='H' \/> by an abelian group <img src='http:\/\/l.wordpress.com\/latex.php?latex=G&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='G' style='vertical-align:1%' class='tex' alt='G' \/> consists of a group <img src='http:\/\/l.wordpress.com\/latex.php?latex=E&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='E' style='vertical-align:1%' class='tex' alt='E' \/> together with an inclusion of <img src='http:\/\/l.wordpress.com\/latex.php?latex=G%20%5Chookrightarrow%20E&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='G \\hookrightarrow E' style='vertical-align:1%' class='tex' alt='G \\hookrightarrow E' \/> as a normal subgroup and a surjective homomorphism <img src='http:\/\/l.wordpress.com\/latex.php?latex=E%20%5Ctwoheadrightarrow%20H&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='E \\twoheadrightarrow H' style='vertical-align:1%' class='tex' alt='E \\twoheadrightarrow H' \/> that displays <img src='http:\/\/l.wordpress.com\/latex.php?latex=H&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='H' style='vertical-align:1%' class='tex' alt='H' \/> as the quotient group <img src='http:\/\/l.wordpress.com\/latex.php?latex=E%7CG&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='E|G' style='vertical-align:1%' class='tex' alt='E|G' \/>.<\/p><\/blockquote>\n<p>If you&#8217;re not a professional mathematician, then that is pure gobbledigook. But that seems to be typical of how initiates of category theory talk about it. But the basic concepts, while abstract, really aren&#8217;t all that tricky. In many ways, it feels a lot like set theory: there&#8217;s a simple conceptual framework, on which you can build extremely complicated formalisms. The difference is that while many people have spent years figuring out how to make the basics of set theory accessible to lay-people, but that effort hasn&#8217;t been applied to set theory.<\/p>\n<h2>What\u2019s the point?<\/h2>\n<p>Ok, so why should you care about category theory?<\/p>\n<p>Category theory is a different way of thinking, and it&#8217;s a language for talking about abstractions. The heart of engineering is abstraction. We take problems, and turn them into abstract structures. We look at the structures we create, and recognize commonalities between those structures, and then we create new abstractions based on the commonalities. The hardest part of designing a good library is identifying the right abstractions.<\/p>\n<p>Category theory is a tool for talking about structures, which is particularly well suited to thinking about software. In category theory, we think in terms of <em>arrows<\/em>, where arrows are mappings between objects. We&#8217;ll see what that means in detail later, but the gist of it is that one example of arrows mapping between objects is functions mapping between data types in a computer program.<\/p>\n<p>Category theory is built on thinking with orrows, and building structures using arrows. It\u2019s about looking at mathematical constructions built with arrows, and in those structures, figuring out what the fundamental parts are. When we abstract enough, we can start to see that things that look very different are really just different realizations of the same underlying structure. Category theory gives us a language and a set of tools for doing that kind of abstraction &#8211; and then we can take the abstract structures that we identify, and turn them into code &#8211; into very generic libraries that express deep, fundamental structure.<\/p>\n<h1>Start with an Example: Monoids<\/h1>\n<h2>Monoids in Code<\/h2>\n<p>We&#8217;ll get started by looking at a simple mathematical structure called a monoid, and how we can implement it in code; and then, we&#8217;ll move on to take an informal look at how it works in terms of categories.<\/p>\n<p>Most of the categorical abstractions in Scala are implemented using something called a typeclass, so we&#8217;ll start by looking at typeclasses. Typeclasses aren&#8217;t a category theoretical notion, but they make it much, much easier to build categorical structures. And they do give us a bit of categorical flavor: a typeclass defines a kind of metatype &#8211; that is, a type of type &#8211; and we\u2019ll see, that kind of self-reflective abstraction is a key part of category theory.<\/p>\n<p>The easiest way to think about typeclasses is that they&#8217;re a kind of metatype &#8211; literally, as the name suggests, they define classes where the elements of those classes are types. So a typeclass provides an interface that a type must provide in order to be an instance of the metatype. Just like you can implement an interface in a type by providing implementations of its methods, you can implement a typeclass by providing implementations of its operations.<\/p>\n<p>In Scala, you implement the operations of a typeclasses using a language construct called an implicit parameter. The implicit parameter attaches the typeclass operations to a meta-object that can be passed around the program invisibly, providing the typeclass&#8217;s operations.<\/p>\n<p>Let&#8217;s take a look at an example. An operation that comes up very frequently in any kind of data processing code is reduction: taking a collection of values of some type, and combining them into a single value. Taking the sum of a list of integers, the product of an array of floats, and the concatenation of a list of strings are all examples of reduction. Under the covers, these are all similar: they&#8217;re taking an ordered group of values, and performing an operation on them. Let&#8217;s look at a couple of examples of this:<\/p>\n<pre>def reduceFloats(floats: List[Float]): Float =\n    floats.foldRight(0)((x, y) =&gt; x + y)\n\ndef reduceStrings(strings: Seq[String]): String =\n    strings.foldRight(\"\")((x, y) =&gt; x.concat(y))\n<\/pre>\n<p>When you look at the code, they look very similar. They&#8217;re both just instantiations of the same structural pattern:<\/p>\n<pre>def reduceX(xes: List[X]): X =\n    xes.foldRight(xIdentity)((a, b) =&gt; Xcombiner(a, b))\n<\/pre>\n<p>The types are different; the actual operation used to combine the values is different; the base value in the code is different. But they&#8217;re both built on the same pattern:<\/p>\n<ul>\n<li>There&#8217;s a type of values we want to combine: <code>Float<\/code> or <code>String<\/code>. Everything we care about in reduction is a connected with this type.<\/li>\n<li>There&#8217;s a collection of values that we want to combine, from left to right. In one case, that&#8217;s a <code>List[Float]<\/code>, and in the other, it&#8217;s a <code>Seq[String]<\/code>. The type doesn&#8217;t matter, as long as we can iterate over it.<\/li>\n<li>There&#8217;s an identity value that we can use as a starting point for building the result; <code>0<\/code> for the floats, and <code>\"\"<\/code> (the empty string) for the strings.<\/li>\n<li>There&#8217;s an operation to combine two values: <code>+<\/code> for the floats, and <code>concat<\/code> for the strings.<\/li>\n<\/ul>\n<p>We can capture that concept by writing an interface (a trait, in Scala terms) that captures it; that interface is called a typeclass. It happens that this concept of reducible values is called a monoid in abstract algebra, so that&#8217;s the name we&#8217;ll use.<\/p>\n<pre>trait Monoid[A]  {\n    def empty: A\n    def combine(x: A, y: A): A\n}\n<\/pre>\n<p>We can read that as saying &#8220;A is a monoid if there are implementations of empty and combine that meet these constraints&#8221;. Given the declaration of the typeclass, we can implement it as an object which provides those operations for a particular type:<\/p>\n<pre>object FloatAdditionMonoid extends Monoid[Float] {\n    def empty: Float = 0.0\n    def combine(x: Float, y: Float): Float = x + y\n}\n\nobject StringConcatMonoid extends Monoid[String] {\n    def empty: String = \"\"\n    def combine(x: String, y: String): String = x.concat(y)\n}\n<\/pre>\n<p><code>FloatAdditionMonoid<\/code> implements the typeclass <code>Monoid<\/code> for the type <code>Float<\/code>. And since we can write an implementation of <code>Monoid<\/code> for <code>Float<\/code> or <code>String<\/code>, we can say that the types <code>Float<\/code> and <code>String<\/code> are instances of the typeclass <code>Monoid<\/code>.<\/p>\n<p>Using our implementation of <code>Monoid<\/code>, we can write a single, generic reduction operator now:<\/p>\n<pre>def reduce[A](values: Seq[A], monoid: Monoid[A]): A =\n   values.foldRight(monoid.empty)(monoid.combine)\n<\/pre>\n<p>We can use that to reduce a list of floats:<\/p>\n<pre>reduce([1.0, 3.14, 2.718, 1.414, 1.732], FloatAdditionMonoid)\n<\/pre>\n<p>And we can do a bit better than that! We can set up an <em>implicit<\/em>, so that we don&#8217;t need to pass the monoid implementation around. In Scala, an implicit is a kind of dynamically scoped value. For a given type, there can be one implicit value of that type in effect at any point in the code. If a function takes an implicit parameter of that type, then the nearest definition in the execution stack will automatically be inserted if the parameter isn&#8217;t passed explicitly.<\/p>\n<pre>def reduce[A](values: Seq[A])(implicit A: Monoid[A]): A =\n   list.foldRight(A.empty)(A.combine)\n<\/pre>\n<p>And as long as there&#8217;s a definition of the <code>Monoid<\/code> for a type <code>A<\/code> in scope, we can can use that now by just writing:<\/p>\n<pre>implicit object FloatAdditionMonoid extends Monoid[Float] {\n    def empty: Float = 0.0\n    def combine(x: Float, y: Float): Float = x + y\n}\n\nval floats: List[Float] = ...\nval result = reduce(floats)\n<\/pre>\n<p>Now, anywhere that the <code>FloatAdditionMonoid<\/code> declaration is imported, you can call reduce on any sequence of floats, and the implicit value will automatically be inserted.<\/p>\n<p>Using this idea of a monoid, we&#8217;ve captured the concept of reduction in a common abstraction. Our notion of reduction doesn&#8217;t care about whether we&#8217;re reducing strings by concatenation, integers by addition, floats by multiplication, sets by union. Those are all valid uses of the concept of a monoid, and they&#8217;re all easy to implement using the monoid typeclass. The concept of monoid isn&#8217;t a difficult one, but at the same time, it&#8217;s not necessarily something that most of us would have thought about as an abstraction.<\/p>\n<p>We&#8217;ve got a typeclass for a monoid; now, we&#8217;ll try to connect it into category theory. It&#8217;s a bit tricky, so we won&#8217;t cover it all at once. We&#8217;ll look at it a little bit now, and we&#8217;ll come back to it in a later lesson, after we&#8217;ve absorbed a bit more.<\/p>\n<h3>From Sets to Arrows<\/h3>\n<p>For most of us, if we&#8217;ve heard of monoids, we&#8217;ve heard of them in terms of set theory and abstract algebra. So in that domain, what&#8217;s a monoid?<\/p>\n<p>A monoid is a triple <img src='http:\/\/l.wordpress.com\/latex.php?latex=%28V%2C%201%2C%20%2A%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(V, 1, *)' style='vertical-align:1%' class='tex' alt='(V, 1, *)' \/>, where:<\/p>\n<ul>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=V&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='V' style='vertical-align:1%' class='tex' alt='V' \/> is a set of values;<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=1&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='1' style='vertical-align:1%' class='tex' alt='1' \/> is a value in <img src='http:\/\/l.wordpress.com\/latex.php?latex=V&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='V' style='vertical-align:1%' class='tex' alt='V' \/>;<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%2A&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='*' style='vertical-align:1%' class='tex' alt='*' \/> is a total binary operator where:\n<ul>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=1&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='1' style='vertical-align:1%' class='tex' alt='1' \/> is an identity of <img src='http:\/\/l.wordpress.com\/latex.php?latex=%2A&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='*' style='vertical-align:1%' class='tex' alt='*' \/>: For any value <img src='http:\/\/l.wordpress.com\/latex.php?latex=v%20%5Cin%20V%3A%20v%2A1%20%3D%201%2Av%20%3D%20v&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='v \\in V: v*1 = 1*v = v' style='vertical-align:1%' class='tex' alt='v \\in V: v*1 = 1*v = v' \/>.<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%2A&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='*' style='vertical-align:1%' class='tex' alt='*' \/> is associative: for any values <img src='http:\/\/l.wordpress.com\/latex.php?latex=v%2C%20w%2C%20x%20%5Cin%20V%3A%20%28v%20%2A%20w%29%20%2A%20x%20%3D%20v%20%2A%20%28w%20%2A%20x%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='v, w, x \\in V: (v * w) * x = v * (w * x)' style='vertical-align:1%' class='tex' alt='v, w, x \\in V: (v * w) * x = v * (w * x)' \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>That\u2019s all just a formal way of saying that a monoid is a set with a binary associative operator and an identity value. The set of integers can form a monoid with addition as the operator, and 0 as identity. Real numbers can be a monoid with multiplication and 1. Strings can be a monoid with concatenation as the operator, and empty string as identity.<\/p>\n<p>But we can look at it in a different way, too, by thinking entirely in terms of function.<br \/>\nLet&#8217;s forget about the numbers as individual values, and instead, let&#8217;s think about them in functional terms. Every number is a function which adds itself to its parameter. So &#8220;2&#8221; isn&#8217;t a number, it&#8217;s a function which adds two to anything.<\/p>\n<p>How can we tell that 2 is a function which adds two to things?<\/p>\n<p>If we compose it with 3 (the function that adds three to things), we get 5 (the function that adds five to things). And how do we know that? Because it&#8217;s the same thing that we get if we compose 3 with 1, and then compose the result of that with 1 again. 3+1+1=5, and 3+2=5. We can also tell that it&#8217;s 2, because if we just take 1, and compose it with itself, what we&#8217;ll get back is the object that we call 2.<\/p>\n<p>In this scheme, all of the numbers are related not by arithmetic, not by an underlying concept of quantity or cardinality or ordinality, but only by how they compose with each other. We can&#8217;t see anything else &#8211; all we have are these functions. But we can recognize that they are the natural numbers that we&#8217;re familiar with.<\/p>\n<p>Looking at it this way, we can think of the world of natural numbers as a single point, which represents the set of all natural numbers. And around that point, we&#8217;ve got lots and lots of arrows, each of which goes from that point back to itself. Each of those arrows represents one number. The way we tell them apart is by understanding which arrow we get back when we compose them. Take any arrow from that point back to that point, and compose it with the arrow 0, and what do you get? The arrow you started with. Take any arrow that you want, and compose it with 2. What do you get? You get the same thing that you&#8217;d get if you composed it with 1, and then composed it with one again.<\/p>\n<p>That dot, with those arrows, is a category.<\/p>\n<p>What kind of advantage do we get in going from the algebraic notion of a set with a binary operation, to the categorical notion of an object with a bunch of composable arrows? It allows to understand a monoid purely as a structure, without having the think about what the objects are, or what the operator means.<\/p>\n<p>Now, let&#8217;s jump back to our monoid typeclass for a moment.<\/p>\n<pre>trait Monoid[A]  {\n    def empty: A\n    def combine(x: A, y: A): A\n}\n<\/pre>\n<p>We can understand this as being a programmable interface for the categorical object that we just described. All we need to do is read &#8220;:&#8221; as &#8220;is an arrow in&#8221;: It says that A is a monoid if:<\/p>\n<ul>\n<li>It has an element called empty which is an arrow in A.<\/li>\n<li>It has an operation called combine which, given any two arrows in A, composes them into a new arrow in A.<\/li>\n<\/ul>\n<p>There are, of course, other conditions &#8211; combine needs to be associative, and empty needs to behave as the identity value. But just like when we write an interface for, say, a binary search tree, the interface only defines the structure not the ordering condition, the typeclass defines the functional structure of the categorical object, not the logical conditions.<\/p>\n<p>This is what categories are really all about: tearing things down to a simple core, where everything is expressed in terms of arrows. It\u2019s almost reasoning in functions, except that it\u2019s even more abstract than that: the arrows don\u2019t need to be functions &#8211; they just need to be composable mappings from things to things.<\/p>\n<h2>Deeper Into Arrows<\/h2>\n<p>We can abstract a bit more, and look at the entire construction, including the identity and associativity constraints entirely in terms of arrows. To really understand this, we\u2019ll need to spend some time diving deeper into the actual theory of categories, but as a preview, we can describe a monoid with the following pair of diagrams (copied from wikipedia):<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.goodmath.org\/blog\/wp-content\/uploads\/2018\/10\/cat-monoid.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-3629\" src=\"https:\/\/i0.wp.com\/www.goodmath.org\/blog\/wp-content\/uploads\/2018\/10\/cat-monoid.jpg?resize=225%2C300\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/i0.wp.com\/www.goodmath.org\/blog\/wp-content\/uploads\/2018\/10\/cat-monoid.jpg?resize=225%2C300 225w, https:\/\/i0.wp.com\/www.goodmath.org\/blog\/wp-content\/uploads\/2018\/10\/cat-monoid.jpg?w=242 242w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>In these diagrams, any two paths between the same start and end-nodes are equivalent (up to isomorphism). When you understand how to read this diagrams, these really do define everything that we care about for monoids.<\/p>\n<p>For now, we\u2019ll just run through and name the parts &#8211; and then later, in another lesson, we\u2019ll come back, and we\u2019ll look at this in more detail.<\/p>\n<ul>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%5Cmu&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='\\mu' style='vertical-align:1%' class='tex' alt='\\mu' \/> is an arrow from <img src='http:\/\/l.wordpress.com\/latex.php?latex=M%5Ctimes%20M%20%5Crightarrow%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='M\\times M \\rightarrow M' style='vertical-align:1%' class='tex' alt='M\\times M \\rightarrow M' \/>, which we\u2019ll call a multiplication operator.<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%5Ceta&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='\\eta' style='vertical-align:1%' class='tex' alt='\\eta' \/> is an arrow from <img src='http:\/\/l.wordpress.com\/latex.php?latex=I%20%5Crightarrow%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='I \\rightarrow M' style='vertical-align:1%' class='tex' alt='I \\rightarrow M' \/>, called unit.<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%5Calpha&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='\\alpha' style='vertical-align:1%' class='tex' alt='\\alpha' \/> is an arrow from <img src='http:\/\/l.wordpress.com\/latex.php?latex=%28M%5Ctimes%20M%29%5Ctimes%20M%20%5Crightarrow%20M%20%5Ctimes%20%28M%5Ctimes%20M%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(M\\times M)\\times M \\rightarrow M \\times (M\\times M)' style='vertical-align:1%' class='tex' alt='(M\\times M)\\times M \\rightarrow M \\times (M\\times M)' \/> which represents the associativity property of the monoid.<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%5Clambda&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='\\lambda' style='vertical-align:1%' class='tex' alt='\\lambda' \/> is a morphism which represents the left identity property of the monoid (that is, <img src='http:\/\/l.wordpress.com\/latex.php?latex=1%2Ax%3Dx&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='1*x=x' style='vertical-align:1%' class='tex' alt='1*x=x' \/>), and <img src='http:\/\/l.wordpress.com\/latex.php?latex=%5Crho&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='\\rho' style='vertical-align:1%' class='tex' alt='\\rho' \/> is a morphism representing the right identity property <img src='http:\/\/l.wordpress.com\/latex.php?latex=%28x%2A1%3Dx%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(x*1=x)' style='vertical-align:1%' class='tex' alt='(x*1=x)' \/>.<\/li>\n<\/ul>\n<p>This diagram, using these arrows, is a way of representing all of the key properties of a monoid via nothing but arrows and composition. It says, among other things, that:<\/p>\n<ul>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%28M%20%5Ctimes%20M%29%20%5Ctimes%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(M \\times M) \\times M' style='vertical-align:1%' class='tex' alt='(M \\times M) \\times M' \/> composes with multiplication to be <img src='http:\/\/l.wordpress.com\/latex.php?latex=M%20%5Ctimes%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='M \\times M' style='vertical-align:1%' class='tex' alt='M \\times M' \/>.<br \/>\nThat is, applying multiplication to <img src='http:\/\/l.wordpress.com\/latex.php?latex=%28M%20%5Ctimes%20M%29%20%5Ctimes%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(M \\times M) \\times M' style='vertical-align:1%' class='tex' alt='(M \\times M) \\times M' \/> evaluates to (M \\times M).<\/li>\n<li><img src='http:\/\/l.wordpress.com\/latex.php?latex=%28M%20%5Ctimes%20M%29%20%5Ctimes%20M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='(M \\times M) \\times M' style='vertical-align:1%' class='tex' alt='(M \\times M) \\times M' \/> composed with associativity can become <img src='http:\/\/l.wordpress.com\/latex.php?latex=M%20%5Ctimes%20%28M%20%5Ctimes%20M%29&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='M \\times (M \\times M)' style='vertical-align:1%' class='tex' alt='M \\times (M \\times M)' \/>.<\/li>\n<\/ul>\n<p>So it\u2019s a monoid &#8211; but it\u2019s a higher level monoid. In this, <img src='http:\/\/l.wordpress.com\/latex.php?latex=M&#038;bg=FFFFFF&#038;fg=000000&#038;s=0' title='M' style='vertical-align:1%' class='tex' alt='M' \/> isn\u2019t just an object in a category: it\u2019s an entire category. These arrows are arrows between categories in a category of categories.<\/p>\n<p>What we\u2019ll see when we get deeper into category theory is how powerful this kind of abstraction can get. We\u2019ll often see a sequence of abstractions, where we start with a simple concept (like monoid), and find a way to express it in terms of arrows between objects in a category. But then, we\u2019ll lift it up, and look at how we can see in not just as a relation between objects in a category, but as a different kind of relation between categories, by constructing the same thing using a category of categories. And then we\u2019ll abstract even further, and construct the same thing using mappings between categories of categories.<\/p>\n<p>(You can find the next lesson &lt;a href=&#8221;http:\/\/www.goodmath.org\/blog\/2019\/02\/20\/category-theory-lesson-2-basics-of-categorical-abstraction\/&#8221;&gt;here&lt;\/a&gt;.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction and Motivation One thing that I keep bumping up against as an engineer who loves functional a programming is category theory. It often seems like there are two kinds of functional programmers: people who came into functional programming via engineering, and people who came into functional programming via math. The problem is that a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[76,1],"tags":[],"class_list":["post-3580","post","type-post","status-publish","format-standard","hentry","category-category-theory","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-VK","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/3580","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=3580"}],"version-history":[{"count":15,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/3580\/revisions"}],"predecessor-version":[{"id":3767,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/3580\/revisions\/3767"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=3580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=3580"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=3580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}