Jekyll2018-08-10T19:27:10-07:00https://dzackgarza.com/D. Zack GarzaHome of my personal blog, online projects, and various articles on MathematicsD. Zack Garzadzackgarza@gmail.comA Brief Introduction to Category Theory2017-01-08T00:00:00-08:002017-01-08T00:00:00-08:00https://dzackgarza.com/brief-intro-to-category-theory-1<div class="mume markdown-preview ">
<h1 class="mume-header" id="disclaimer">Disclaimer</h1>
<p>This is meant to be a relatively short and <strong>non-rigorous</strong> introduction to Category Theory. Although I will be defining and using a lot of the technical terminology that is commonly used, this talk is primarily aimed at introducing these concepts, why they exist, and where they’re useful and commonly used.</p>
<p>In fact, most of the results used here will be stated with very minimal proof – this is partly due to time constraints, and diving into them here would obfuscate the more high-level points I’d like to make. However, if you are interested in seeing and working through some of these types of proofs yourself, I’ve included some references that I’d recommend near the end.</p>
<h1 class="mume-header" id="introduction">Introduction</h1>
<p>Of course, if we’re going to talk about Category Theory, I should probably start by telling you what it is! However, instead of diving into the definitions immediately, I think it helps to have some motivation for <em>why</em> such a thing should even exist in the first place.</p>
<p>Category Theory was conceived (or invented, or discovered; whichever you prefer) in 1945 by Samuel Eilenberg and Saunders Mac Lane while working on something called the Cech cohomology, which is central in the field of algebraic topology.</p>
<p>One of Eilenberg and Mac Lane’s motivations was that it was (and still is!) common among mathematicians to refer to certain constructions as “natural” and “canonical” – broadly speaking, these terms are used to denote constructions that were somehow “choice-free”. For example, one might want to study vector spaces without explicitly choosing a basis vectors. In this way, one can discover properties that don’t actually <em>depend</em> on a particular frame of reference, and in some sense are more “universal” and intrinsic to the object being studied.</p>
<p>In particular, Eilenberg and Mac Lane wanted to formalize the notion of a <strong>natural transformation</strong> and things that were “naturally isomorphic.”</p>
<h2 class="mume-header" id="interlude-what-does-natural-mean">Interlude – What does “natural” mean?</h2>
<hr />
<p>A canonical example from mathematics is that, given a finite-dimensional vector space <span class="mathjax-exps">$V$</span> over a field <span class="mathjax-exps">$k$</span> (you can just take <span class="mathjax-exps">$k=\mathbb{R}$</span> here if you’d like), one can look at it’s <em>dual space</em>, denoted <span class="mathjax-exps">$V^*$</span>, which is the space of all functions <span class="mathjax-exps">$f : V \rightarrow k$</span> that take vectors in <span class="mathjax-exps">$V$</span> as input and output scalars in the base field <span class="mathjax-exps">$k$</span>. It turns out that <span class="mathjax-exps">$V^*$</span> is also a vector space, with the same dimension as <span class="mathjax-exps">$V$</span>, and one result you might remember from linear algebra is that <span class="mathjax-exps">$\text{dim} V = n \Rightarrow V \cong R^n$</span> – that is, all vector spaces of finite dimension <span class="mathjax-exps">$n$</span> are indistinguishable (as vector spaces) from <span class="mathjax-exps">$\mathbb{R}^n$</span>.</p>
<p>In particular, we have <span class="mathjax-exps">$\text{dim}~V^* = n$</span>, so <span class="mathjax-exps">$V^* \cong R^n \cong V$</span>. So <span class="mathjax-exps">$V$</span> is isomorphic to its dual.</p>
<p>But <span class="mathjax-exps">$V^*$</span> is a vector space in its own right, so we can look at <em>it’s</em> dual too! This is denoted <span class="mathjax-exps">$V^{**}$</span>, and sometimes referred to as the "double dual" of <span class="mathjax-exps">$V$</span>. In exactly the same way, we find that <span class="mathjax-exps">$\text{dim}V^{**} =n$</span> as well, and so <span class="mathjax-exps">$V^{**} \cong V^*$</span>, and so we can conclude that <span class="mathjax-exps">$V \cong V^{**}$</span> – that is, <span class="mathjax-exps">$V$</span> is isomorphic to its double dual.</p>
<p>So <span class="mathjax-exps">$V$</span> is isomorphic to <span class="mathjax-exps">$V^*$</span>, and it is also isomorphic to <span class="mathjax-exps">$V^{**}$</span>. However, when one goes through the process of actually finding and constructing these bijections, one finds that the map from <span class="mathjax-exps">$V \rightarrow V^{*}$</span> truly depends on choosing a basis for <span class="mathjax-exps">$V$</span>; on the other hand, the map from <span class="mathjax-exps">$V$</span> to <span class="mathjax-exps">$V^{**}$</span> requires <em>no such choice</em>. In this way, we say that <span class="mathjax-exps">$V$</span> is isomorphic to its dual, but <span class="mathjax-exps">$V$</span> is <em>naturally</em> isomorphic to it’s double dual.</p>
<hr />
<p>This idea of “naturality” is part of what category theory sets out to make precise.</p>
<p>A secondary motivation was to abstract away properties that are really only a result of some particular structure or construction, and don’t actually have much to do with the specific kind of object you’re working with. (If you’ve programmed much, the analog here would be “refactoring” commonly used pieces of code into a more general interface.)</p>
<p>A few such constructions would be things like products or quotients of objects, which are ubiquitous in mathematics. With products, for example, it is possible to construct a product of sets (which have very little structure), but we can also construct a product of vector spaces (which have a very rich structure). It’s then natural to ask, what commonalities do these constructions share? Which properties of a product of vector spaces are due to them being vector spaces, and which are just a result of its construction as a product? This is another area where category theory shines; notions such as products and quotients can be described in terms of <em>universal properties</em>, which pay no heed to what the underlying objects really are at all.</p>
<p>As a result, Category Theory provides a way of describing things in ways that are general enough be applied very broadly. It is useful as both an organizational tool, and also as a general language and logical framework which has found use not only in various branches mathematics, but also in logic, computer science, physics, philosophy, linguistics, and a host of other fields.</p>
<p>On one hand, it serves as “simplification through abstraction” – we move from studying individual trees to studying the forest as a whole. On the other hand, it also allows us to reason about entire collections of forests, and how to transport our findings from one forest to another.</p>
<p>In a nutshell, categories were invented as a framework to support <strong>functors</strong>, which were in turn invented to describe <strong>natural transformations</strong> between objects, which are in turn used to define <strong>adjoints</strong>. Of course, many other useful categorical tools have been developed, adjunction is really one of<strong>the</strong> key notions that category theory is meant to describe support.</p>
<h2 class="mume-header" id="interlude-what-is-an-adjoint">Interlude – What is an adjoint?</h2>
<hr />
<p>Adjunction is a slightly complicated concept, but informally speaking, <strong>functors</strong> map categories into other categories, and adjoints allow you to “approximate” one category by another. And in some cases, there is also an “inverse” to this approximation which takes you back to the original category.</p>
<p>For example, consider groups and sets; there are categories <span class="mathjax-exps">$\mathbf{Grp}$</span> and <span class="mathjax-exps">$\mathbf{Set}$</span> in which these objects live. A group is really just a set that is decorated with some additional structure – in this case, a binary operation that essentially behaves like modular addition. Usually groups are given to you with an <em>a priori</em> notion of what this operation is, but what if this weren’t the case? If you were just given a set, is there any way to "upgrade" it to a group?</p>
<p>The answer is yes; if <span class="mathjax-exps">$X$</span> is any set, there is a construction called the <em>free group on</em> <span class="mathjax-exps">$X$</span>, denoted <span class="mathjax-exps">$F(X)$</span>, which goes something like this: given a set like <span class="mathjax-exps">$A = \{a, b\}$</span>, one thinks of <span class="mathjax-exps">$A$</span> as a formal alphabet of symbols, and makes another set of "formal inverses" of <span class="mathjax-exps">$A$</span>, say <span class="mathjax-exps">$B = \{a^{-1}, b^{-1}\}$</span>. Then, take the set <span class="mathjax-exps">$G = A \coprod B = \{a,b,a^{-1},b^{-1}\}$</span> , add an element <span class="mathjax-exps">$\varepsilon$</span> to denote an empty symbol, and define a group operation <span class="mathjax-exps">$\bigstar$</span> that is simply the concatenation of symbols together (subject to no rules or relations other than <span class="mathjax-exps">$x \bigstar \varepsilon = x$</span>). We then stipulate that whenever something like <span class="mathjax-exps">$aa^{-1}$</span> occurs in a string (again, strictly as formal symbols over the alphabet <span class="mathjax-exps">$G$</span>), there is a reduction operation that replaces this with <span class="mathjax-exps">$\varepsilon$</span>. After quotienting out by an equivalence under these reductions, we produce something that is a well-defined group, and is somehow the minimal group that could have been made from the original set and no other information.</p>
<p>Then, there is something called a “forgetful functor” <span class="mathjax-exps">$\mathcal{F}$</span> from <span class="mathjax-exps">$\mathbf{Grp}$</span> into <span class="mathjax-exps">$\mathbf{Set}$</span> that takes a group and gives you only the underlying set, "forgetting" everything about its structure as a group. For example, if one took that group <span class="mathjax-exps">$(\mathbb{Z}_2 = \{0,1\}$</span> with the group operation <span class="mathjax-exps">$0+1 =1+0 = 1, 0+0=1+1=0$</span> (i.e., the <span class="mathjax-exps">$XOR$</span> operation), then applying <span class="mathjax-exps">$\mathcal{F}$</span> to <span class="mathjax-exps">$(\mathbb{Z}_2, XOR)$</span> just gives you a two element set <span class="mathjax-exps">$\{a_0. a_1\}$</span>.</p>
<p>Then <span class="mathjax-exps">$\mathcal{F}$</span> has an adjoint <span class="mathjax-exps">$\mathcal{G}$</span>, which creates the free group on that set, <span class="mathjax-exps">$F(\{a_0, a_1\})$</span>. So if you apply <span class="mathjax-exps">$\mathcal{G} \circ \mathcal{F}$</span> to <span class="mathjax-exps">$\mathbb{Z_2}$</span>, you end up back in <span class="mathjax-exps">$\mathbf{Grp}$</span>, but you don’t get back the same group you started with – indeed, the free group consists of infinitely many strings over the alphabet <span class="mathjax-exps">$a_o, a_1, a_0^{-1}, a_1^{-1}$</span>, while <span class="mathjax-exps">$\mathbb{Z}_2$</span> had only two elements. So this adjunction, the free group, provided a way to reconstruct a minimal group out of the information we lost by applying <span class="mathjax-exps">$\mathcal{F}$</span>. For this reason, you’ll often hear of adjunction as the "the most efficient" solution to a given problem, or as a form of "optimization".</p>
<p>(In this case, however, there was only one group with an underlying set of two elements, so if we knew the adjunction was applied, we could deduce what the original group was!)</p>
<hr />
<h1 class="mume-header" id="definition-of-a-category">Definition of a Category</h1>
<h2 class="mume-header" id="informal-description">Informal Description</h2>
<p>Informally, a category is a collection of <strong>objects</strong> and <strong>arrows</strong> between them. Each arrow has a unique source and a target, both of which are objects, and arrows can be <strong>composed</strong> – this will be precisely defined momentarily.</p>
<p>For example, there is a category <strong>Set</strong> where the objects are just normal sets, and the arrows are functions between sets, and “composition of arrows” is just the usual composition of functions.</p>
<p>In another light, categories can be viewed as <strong>simple directed graphs</strong> (diagrams) which have certain constraints on the edge structure. The nodes are the <strong>objects</strong> of the category, and the edges are <strong>morphisms</strong> between objects which satisfy two properties:<br />
- Every node has an edge to itself<br />
- For any sequence of paths between two nodes, there is a direct path between them.</p>
<p>(In fact, one can always take the “free category” on any directed graph by simply filling in all of the necessary composition morphisms. This is a fun exercise, try it yourself!)</p>
<h2 class="mume-header" id="formal-definitions">Formal Definitions</h2>
<p>Formally, a category <span class="mathjax-exps">$C$</span> is two pieces of data:</p>
<ul>
<li>
<span class="mathjax-exps">$Ob(C)$</span>, the class of <em>objects</em> of <span class="mathjax-exps">$C$</span>,</li>
<li>
<span class="mathjax-exps">$Hom(C)$</span>, the <strong>set</strong> of <em>morphisms</em> between objects in <span class="mathjax-exps">$Ob(C)$</span>
<ul>
<li>Members of <span class="mathjax-exps">$Hom(C)$</span> are denoted <span class="mathjax-exps">$Hom_C(X,Y)$</span>, where <span class="mathjax-exps">$X,Y \in Ob(C)$</span>.</li>
</ul>
</li>
</ul>
<p>Along with a binary operation <span class="mathjax-exps">$\circ$</span> which composes morphisms:</p>
<ul>
<li>
<span class="mathjax-exps">$\forall X,Y,Z \in Ob(C)$</span> where <span class="mathjax-exps">$f: X \rightarrow Y$</span> and <span class="mathjax-exps">$g: Y \rightarrow Z$</span>, there exists the <strong>composition</strong> <span class="mathjax-exps">$h$</span> of <span class="mathjax-exps">$f$</span> and <span class="mathjax-exps">$g$</span>, denoted <span class="mathjax-exps">$h = g \circ f$</span>, where <span class="mathjax-exps">$h: X \rightarrow Z$</span>.</li>
<li>Using types, this operation might be expressed in the following way: <span class="mathjax-exps">$\circ: Hom_C(X,Y) \times Hom_C(Y,Z) \rightarrow Hom_C(X,Z)$</span> <span class="mathjax-exps">$(f \times g) \mapsto g \circ f$</span>
</li>
</ul>
<p>Which satisfies two axioms:</p>
<ul>
<li>Associativity of <span class="mathjax-exps">$\circ$</span>, given by <span class="mathjax-exps">$f\circ(g\circ h) = (f\circ g)\circ h$</span>
</li>
<li>Existence of unique two-sided identities: <span class="mathjax-exps">$\forall X \in Ob(C), \exists id_X \in Hom(C)$</span> where <span class="mathjax-exps">$id_x: X \rightarrow X$</span>. These satisfy
<ul>
<li>
<span class="mathjax-exps">$\forall f: A\rightarrow X \in Hom(A,X), f\circ id_X = f$</span> and</li>
<li>
<span class="mathjax-exps">$\forall g: X \rightarrow B \in Hom(X, B), id_X \circ g = g$</span>.</li>
</ul>
</li>
</ul>
<p>Note that the objects of category are “black boxes” – we have no real information about what is inside of them, so in general we can not talk about elements of an object.</p>
<p><-- #TODO --><br />
Define: functor</p>
<p>Define: adjunction</p>
<p>Define: equivalence of categories</p>
<h2 class="mume-header" id="foundational-issues">Foundational Issues</h2>
<p>Certain collections of objects are “too big” to be sets – for example, we have Russel’s paradox: <span class="mathjax-exps">$(\exists R = \{ x : x \not \in x \}) \Rightarrow (R\in R \iff R\not\in R)$</span>, which must be a contradiction. So strictly speaking, one can not consider a "set of all sets", although we would like to study things like the <em>blah</em> of all sets, for whatever <em>blah</em> we can come up with. In particular, we’d like a category <strong>Set</strong> that contains all sets</p>
<p>The workaround is to use use <strong>classes</strong> (sets with restricted operations). A Class that is a also a normal set is referred to as a <strong>small class</strong>, while classes that are <em>not</em> sets are denoted <strong>proper classes</strong>.</p>
<p>We will take the objects of categories to be proper classes, and in general the morphisms will be small classes and are sometimes referred to as <em>hom-sets</em>, although this is not strictly required. In this sense, category theory actually subsumes set and generalizes the theory of sets – indeed, there are mathematical camps that see categories as an <em>alternative</em> to set theory for the foundation of math. If one is interested in such things, it is worth investigating the ideas of <strong>homotopy type theory</strong> and <strong>topoi</strong>, which might be said to fall under the umbrella of logic.</p>
<h1 class="mume-header" id="examples">Examples</h1>
<p>Since categories can be quite abstract objects, it’s useful to have a few concrete toy examples in mind to check new definitions and theorems against, here are a number of you can use. I’ve tried to collect examples from Algebra, Analysis, and even a few from Computer Science – it is by no means necessary to be familiar with all of these; usually finding a few that you use often and are familiar with is quite sufficient for most purposes.</p>
<hr />
<p>Here, I’ll just cover what I think are the three most important parts of recognizing that some structure you’ve used is a category – the objects, the morphisms, and what kind of morphisms are called isomorphisms in that category. Checking the categorical axioms is pretty routine and perhaps not as enlightening, so we’ll skip that for now.</p>
<p>That being said, here’s how the examples are formatted:</p>
<ul>
<li>
<span class="mathjax-exps">$\mathbf{Name}$</span>: A somewhat informal name I’ve given to the category as a whole. Some names are more "official", but these vary a lot across the literature. Some categories aren’t named at all, so I’ve supplied arbitrary names in some cases. Note that some categories are named after their object classes (<span class="mathjax-exps">$\mathbf{Set}$</span>), while others are actually named after their morphism classes (<span class="mathjax-exps">$\mathbf{Mat}$</span>). Category names are usually typeset in <em>mathbf</em>.
<ul>
<li>
<em>Objects</em>: Describes the entire class <span class="mathjax-exps">$Ob(C)$</span>, and gives an example of what the full data of what two distinct members <span class="mathjax-exps">$X, Y$</span> in <span class="mathjax-exps">$Ob(C)$</span> might look like. I’ve tried to match the notation to the domain-specific notation one might use when working in each individual category.</li>
<li>
<em>Morphisms</em>: Denotes what the entire class <span class="mathjax-exps">$Hom(C)$</span> looks like, as well as what a morphism <span class="mathjax-exps">$f: X \rightarrow Y \in Hom_C(X,Y) \in Hom(C)$</span> looks like.</li>
<li>
<em>Isomorphisms</em>: Denotes what conditions one puts on a morphism <span class="mathjax-exps">$f: X\rightarrow Y$</span> , and perhaps a corresponding morphism <span class="mathjax-exps">$g : Y \rightarrow X$</span>, in order to recognize <span class="mathjax-exps">$X, Y$</span> as isomorphic objects in this category. (Often denoted <span class="mathjax-exps">$X \cong Y$</span>)</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: Some of these categories are constructed, and easier to demonstrate their construction blackboard. I’ve included notes to explain how this is done for a few examples.</p>
<h3 class="mume-header" id="constructions">Constructions</h3>
<p>Here, I’ll explicitly describe the full set of objects, and the full set of morphisms.</p>
<h4 class="mume-header" id="mathbf2-the-minimal-category-on-two-objects">
<span class="mathjax-exps">$\mathbf{2}$</span> (The minimal category on two objects)</h4>
<ul>
<li>Objects: <span class="mathjax-exps">$\{a,b\}$</span> (A category made out of two arbitrary objects)</li>
<li>Morphisms: <span class="mathjax-exps">$\{Id_a: a \mapsto a, Id_b: b \mapsto b\}$</span>
</li>
<li>Isomorphisms: None (There is no morphism from <span class="mathjax-exps">$b$</span> to <span class="mathjax-exps">$a$</span>.)</li>
</ul>
<h4 class="mume-header" id="mathbf2-a-modified-version-of-mathbf2">
<span class="mathjax-exps">$\mathbf{2'}$</span> (A modified version of <span class="mathjax-exps">$\mathbf{2}$</span>)</h4>
<ul>
<li>Objects: <span class="mathjax-exps">$\{a,b\}$</span>
</li>
<li>Morphisms: <span class="mathjax-exps">$\{a \mapsto a, Id_b: b \mapsto b\} \cup \{ \bigstar: a \mapsto b, Id_a: \}$</span>
</li>
<li>Isomorphisms: None (There is no morphism from <span class="mathjax-exps">$b$</span> to <span class="mathjax-exps">$a$</span>.)</li>
</ul>
<p><em>Notes:</em> Here I just took <span class="mathjax-exps">$\mathbf{2}$</span> and added in a single extra morphism. The star symbol is used here just to denote the fact that this mapping is completely made up, and that arrows in categories don’t have to be "functions" in the traditional sense at all. Each arrow is just <em>some</em> way to associate a source object with a target object.</p>
<h4 class="mume-header" id="mathbfn-the-minimal-category-on-n-objects">
<span class="mathjax-exps">$\mathbf{n}$</span> (The minimal category on <span class="mathjax-exps">$n$</span> objects)</h4>
<ul>
<li>Objects: <span class="mathjax-exps">$\{a_1, a_2, \cdots, a_n\}$</span> (A category made out of <span class="mathjax-exps">$n$</span> arbitrary objects)</li>
<li>Morphisms: <span class="mathjax-exps">$\{Id_{a_1}: a_1 \mapsto a_2, Id_{a_2}: a_2 \mapsto a_2, \cdots , Id_{a_n} a_n \mapsto a_n\}$</span>
</li>
<li>Isomorphisms: None (There are no morphism from <span class="mathjax-exps">$a_i$</span> to <span class="mathjax-exps">$a_j$</span> for any <span class="mathjax-exps">$i,j \leq n$</span>)</li>
</ul>
<p><em>Notes</em>: This just shows that you can make a category out of any set of objects by only supplying identity morphisms – such a category is called <em>discrete</em>. Also note that since every object <em>must</em> have an identity morphism anyway, the objects themselves don’t really matter at all. If we wanted, we could just identify every object with its identity morphism and define categories entirely in terms of morphisms. Practically speaking, though, keeping the notion of objects around makes categories a little easier to work with.</p>
<p>Also, note that it didn’t matter that <span class="mathjax-exps">$n$</span> was finite here – this construction works for any set <span class="mathjax-exps">$X$</span>, yielding <span class="mathjax-exps">$\mathbf{Dis(X)}$</span> (the discrete category on <span class="mathjax-exps">$X$</span>)</p>
<h4 class="mume-header" id="mathbf3"><span class="mathjax-exps">$\mathbf{3'}$</span></h4>
<ul>
<li>Objects: <span class="mathjax-exps">$\{a, b\} \cup \{c\}$</span> (A "minimally interesting" extension of <span class="mathjax-exps">$\mathbf{2}$</span>)</li>
<li>Morphisms: <span class="mathjax-exps">$\{\bigstar: a \mapsto b, Id_a: a \mapsto a, Id_b: b \mapsto b\}$</span><br />
<span class="mathjax-exps">$\cup~\{ Id_c: c\mapsto c\}$</span><br />
<span class="mathjax-exps">$\cup~\{\clubsuit: b \mapsto c\}$</span><br />
<span class="mathjax-exps">$\cup~\{ \sharp: a\mapsto c \text{ where } \sharp(a) = (\clubsuit \circ \bigstar)(a) \}$</span>
</li>
<li>Isomorphisms: None (There is no map from <span class="mathjax-exps">$b$</span> to <span class="mathjax-exps">$a$</span>, <span class="mathjax-exps">$c$</span> to <span class="mathjax-exps">$a$</span>, or <span class="mathjax-exps">$b$</span> to <span class="mathjax-exps">$c$</span>.)</li>
</ul>
<p><em>Notes</em>: The wacky symbols are again used to denote that these mappings are absolutely arbitrary.</p>
<p>A quick explanation of what I mean by “minimally interesting”, though: Given <span class="mathjax-exps">$\mathbb{2}$</span>, note that there are really only a few things we can do with it at this point. We could add another morphism, <span class="mathjax-exps">$b \mapsto a$</span>, and we would get a category where <span class="mathjax-exps">$b\cong a$</span>.</p>
<p>The other thing we can do is add in a single object <span class="mathjax-exps">$c$</span>. We are forced to add an identity morphism for this to be a category, which is what the first union in the morphisms section supplies.</p>
<p>At this point, we just have <span class="mathjax-exps">$\mathbf{3}$</span>, so we look to modify the morphisms a bit to get something slightly different. There are a few choices here, but we’ll go with one of the more interesting ones: a morphism <span class="mathjax-exps">$\clubsuit$</span> from an existing object <span class="mathjax-exps">$b$</span> to the new object <span class="mathjax-exps">$c$</span>.</p>
<p>However, this won’t be a category unless it satisfies the axiom of composition, so we’re forced to add in a morphism that looks like <span class="mathjax-exps">$\sharp$</span>.</p>
<p>Denote<br />
- <span class="mathjax-exps">$\bigstar$</span> by <span class="mathjax-exps">$f$</span><br />
- <span class="mathjax-exps">$\clubsuit$</span> by <span class="mathjax-exps">$g$</span><br />
- <span class="mathjax-exps">$\sharp$</span> by <span class="mathjax-exps">$g \circ f$</span>,</p>
<p>and you get something that perhaps looks a little more familiar:</p>
<p><img src="https://i.imgur.com/016ixGX.png" alt="The Category 3" /></p>
<p>If you haven’t seen this before, don’t worry – I am sure you will! This particular “shape” of diagram shows up in many algebraic constructions (quotients and products, to name a few), and understanding it is the first step in getting a handle on things like universal properties.</p>
<h3 class="mume-header" id="more-standard-examples">More Standard Examples</h3>
<p>Here are some common examples of categories that arise in various contexts, roughly in increasing order of complexity.</p>
<h4 class="mume-header" id="mathbfset"><span class="mathjax-exps">$\mathbf{Set}$</span></h4>
<ul>
<li>Objects: Sets <span class="mathjax-exps">$A, B$</span>
</li>
<li>Morphisms: Set functions <span class="mathjax-exps">$f: A \rightarrow B$</span>
</li>
<li>Isomorphisms: Bijective set functions <span class="mathjax-exps">$f: A\rightarrow B$</span>
<ul>
<li>
<span class="mathjax-exps">$f$</span> is bijective iff <span class="mathjax-exps">$f$</span> is both
<ul>
<li>injective: <span class="mathjax-exps">$\forall a_1, a_2 \in A, f(a_1) = f(a_2) \Rightarrow a_1 = a_2$</span>
<ul>
<li>This lets you construct a <em>left inverse</em>
</li>
</ul>
</li>
<li>surjective: <span class="mathjax-exps">$\forall b \in B, \exists a\in A : b = f(a)$</span>
<ul>
<li>This lets you construct a <em>right inverse</em>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: These conditions allow you to construct a <span class="mathjax-exps">$g: B\rightarrow A$</span> such that</p>
<ul>
<li>
<span class="mathjax-exps">$\forall b\in B, (f\circ g)(b) = b$</span>
<ul>
<li>(i.e. <span class="mathjax-exps">$f\circ g = id_B$</span> as a function)</li>
</ul>
</li>
<li>
<span class="mathjax-exps">$\forall a \in A, g\circ f(a) = a$</span>
<ul>
<li>(i.e. <span class="mathjax-exps">$g\circ f = id_A$</span> as a function)</li>
</ul>
</li>
</ul>
<p>So we refer to <span class="mathjax-exps">$g$</span> as <strong>the</strong> two-sided inverse and call it <span class="mathjax-exps">$f^{-1}$</span>, which is unique when it exists. In many common cases, the objects in a category are "built" out of sets. These categories are called concrete, and the isomorphisms in these categories end up just being isomorphisms of the underlying sets, along with some other structure-preserving conditions. Thus understanding how morphisms and isomorphisms in <span class="mathjax-exps">$\mathbf{Set}$</span> are constructed is a key first step.</p>
<h4 class="mume-header" id="mathbfposet"><span class="mathjax-exps">$\mathbf{Poset}$</span></h4>
<ul>
<li>Objects: Partially-ordered sets <span class="mathjax-exps">$(P \leq)$</span>, <span class="mathjax-exps">$(Q, \prec)$</span>
<ul>
<li>Recall that partial orders are reflexive, transitive, antisymmetric binary operations.</li>
</ul>
</li>
<li>Morphisms: Set functions <span class="mathjax-exps">$f: P \rightarrow Q$</span>
</li>
<li>Isomorphisms: Bijective functions <span class="mathjax-exps">$f: P \rightarrow Q$</span> such that<br />
if <span class="mathjax-exps">$x,y\in P$</span> and <span class="mathjax-exps">$x\leq y$</span>, then <span class="mathjax-exps">$f(x) \prec f(y)$</span>
</li>
</ul>
<h4 class="mume-header" id="mathbfrel"><span class="mathjax-exps">$\mathbf{Rel}$</span></h4>
<ul>
<li>Objects: Binary Relations <span class="mathjax-exps">$(X, \sim), (Y, \propto)$</span>
<ul>
<li>Here <span class="mathjax-exps">$X$</span> is just a set and <span class="mathjax-exps">$\sim \subseteq X\times X$</span> is a binary relation.</li>
</ul>
</li>
<li>Morphisms: Relation-preserving set functions <span class="mathjax-exps">$f: X \rightarrow Y$</span> such that <span class="mathjax-exps">$\forall a,b\in X, a\sim b \Rightarrow f(a)\propto f(b)$</span>
</li>
<li>Isomorphims: Bijective set functions (as in <span class="mathjax-exps">$\mathbf{Set}$</span>) with an inverse <span class="mathjax-exps">$g: Y \rightarrow X$</span> such that <span class="mathjax-exps">$\forall c,d \in Y, c \propto d \Rightarrow g(c) \sim g(d)$</span>.</li>
</ul>
<p><em>Notes</em>: This works for any binary relation – for example, take <span class="mathjax-exps">$\mathbb{Z}$</span> with <span class="mathjax-exps">$a \sim b$</span> iff <span class="mathjax-exps">$a$</span> divides <span class="mathjax-exps">$b$</span>.</p>
<p>Also notice that to get an isomorphism, all we really did was take an isomorphism on the underlying set, and required that the inverse also satisfied the conditions of the morphisms in this category. So really, it required <span class="mathjax-exps">$f$</span> to be bijective in <span class="mathjax-exps">$\mathbf{Set}$</span>, then <span class="mathjax-exps">$g=f^{-1}$</span> just needed to <em>also be morphism in</em> <span class="mathjax-exps">$\mathbf{Rel}$</span>. We’ll see this pattern in almost every concrete category!</p>
<h4 class="mume-header" id="mathbfgrp"><span class="mathjax-exps">$\mathbf{Grp}$</span></h4>
<ul>
<li>Objects: Groups <span class="mathjax-exps">$(G, \star), (H, \diamond)$</span>
</li>
<li>Morphisms: Group homomorphisms <span class="mathjax-exps">$\varphi: (G, \star) \rightarrow (H, \diamond)$</span> where <span class="mathjax-exps">$\forall x,y \in G$</span>, <span class="mathjax-exps">$\phi(x\star y) = \phi(x) \diamond \phi(y)$</span>
</li>
<li>Isomorphisms: Bijective group homomorphisms.
<ul>
<li>These are found by finding a <span class="mathjax-exps">$\varphi$</span> that is bijective as a set function (as described in <span class="mathjax-exps">$\mathbf{Set}$</span>) that is almost a homomorphism (as described above).</li>
<li>Then <span class="mathjax-exps">$\phi^{-1}$</span> can be constructed as a set function, and a result from group theory shows that <span class="mathjax-exps">$\phi^{-1}$</span> is also a homomorphism.</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: This is the first case in a very common pattern – the isomorphisms in this category were just set bijections, <em>but they preserve the structure of the objects</em>. In this case, homomorphisms end up being the kind of morphisms you need to preserve the fundamental pieces of a group’s structure. They preserve the binary operation (by definition) and associativity (from function composition), but they also end up preserving inverses, identities, and information about the elements themselves like order.</p>
<p>This can be summed up with a wave of the hand by saying that the isomorphisms in a category are just <em>invertible structure-preserving morphisms</em>.</p>
<h4 class="mume-header" id="mathbfring"><span class="mathjax-exps">$\mathbf{Ring}$</span></h4>
<ul>
<li>
<p>Objects: Rings <span class="mathjax-exps">$(R, +, \times)$</span></p>
</li>
<li>
<p>Morphisms: Ring homomorphisms <span class="mathjax-exps">$\varphi: (R, +, \times) \rightarrow (S, \star, \diamond)$</span> where <span class="mathjax-exps">$\varphi(a\times(b+c)) = \varphi(a)\star(\varphi(b) \diamond \varphi(c))$</span></p>
</li>
<li>
<p>Isomorphisms: Bijective ring homomorphisms</p>
</li>
<li>
<p><span class="mathjax-exps">$\mathbf{Ab} = \mathbf{Mod_\mathbb{Z}}$</span></p>
<ul>
<li>Objects: Abelian groups (Left <span class="mathjax-exps">$R$</span>-modules of <span class="mathjax-exps">$\mathbb{Z}$</span>)</li>
<li>Homomorphisms of abelian groups <span class="mathjax-exps">$\varphi: G \rightarrow H$</span>
</li>
<li>Isomorphisms: Bijective group homomorphisms</li>
</ul>
</li>
</ul>
<h4 class="mume-header" id="mathbfvect_k"><span class="mathjax-exps">$\mathbf{Vect_k}$</span></h4>
<ul>
<li>Objects: Vector spaces over a field <span class="mathjax-exps">$k$</span>, say <span class="mathjax-exps">$V, W$</span>
</li>
<li>Morphisms: <span class="mathjax-exps">$k$</span>-linear maps <span class="mathjax-exps">$T: V \rightarrow W$</span>
<ul>
<li>These are maps <span class="mathjax-exps">$T$</span> such that <span class="mathjax-exps">$\forall v_1, v_2 \in V, \forall k\in K$</span>, we have <span class="mathjax-exps">$T(v_1 + kv_2) = T(v_1) + kT(v_2)$</span>.</li>
</ul>
</li>
<li>Isomorphisms: Invertible linear maps
<ul>
<li>These are maps between sets of <em>vectors</em> of <span class="mathjax-exps">$V$</span> and <span class="mathjax-exps">$W$</span> which are bijective functions on these sets (again, just as in <span class="mathjax-exps">$\mathbf{Set}$</span>) with the restriction that they obey the linearity condition from above.</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: The presence of <span class="mathjax-exps">$k$</span> is just a generalization – if you haven’t seen a lot of algebra, you can just take <span class="mathjax-exps">$k=\mathbb{R}$</span> and think of the category of all vector spaces over <span class="mathjax-exps">$\mathbb{R}$</span>. Then an object in this category is just <span class="mathjax-exps">$\mathbb{R^n}$</span> for some <span class="mathjax-exps">$n$</span>, and the maps are just the usual linear maps you’d see in an undergraduate course on linear algebra.</p>
<p>Notice how the pattern seen in <span class="mathjax-exps">$\mathbf{Grp}$</span> continues here – to get an isomorphism, you just look at all of the functions between the underlying sets (this is a large set!), take only the bijections, then filter it even further by taking the bijections which preserve the structure you care about.</p>
<p>Here, the structure-preserving maps in vector spaces end up being <em>linear maps</em>. You might notice that condition of linearity looks very similar to the condition for homomorphisms – only now, the operations in both the source and target are the same.</p>
<p>Informally, this is because you essentially get vector spaces by taking a group, tacking on a field <span class="mathjax-exps">$k$</span>, then adding a few more axioms – so the linearity condition is really just a souped-up homomorphism on the underlying group (here, vectors under addition) that takes into account the remaining axioms (namely, scalar multiplication).</p>
<p>The point of this example is to show that (generally speaking) as more structure is put on the objects, more restrictions will need to be put on the morphisms to retain that structure.</p>
<h4 class="mume-header" id="mathbflogic_0-propositional-or-0-order-logic">
<span class="mathjax-exps">$\mathbf{Logic_0}$</span> (Propositional or "0-order" Logic)</h4>
<ul>
<li>Objects: Propositions <span class="mathjax-exps">$P, Q$</span>
</li>
<li>Morphisms: Deductions defined by <span class="mathjax-exps">$P \Rightarrow Q$</span> or "P implies Q"
<ul>
<li>Also known as deductions</li>
</ul>
</li>
<li>Isomorphisms: Tautologies – equivalent propositions <span class="mathjax-exps">$P, Q$</span> such that <span class="mathjax-exps">$P \iff Q$</span>
</li>
</ul>
<p><em>Notes</em>: This can be thought of as “the category of proofs”, and such a category can be derived from any deductive system. The isomorphisms here are “if and only if” statements, and they are often exploited in Mathematics to create <em>definitions</em>.<br />
(In other words, every Mathematical definition is an iff statement, and any proposition isomorphic to a definition in this category can be taken as an equivalent definition.)</p>
<h4 class="mume-header" id="mathbfaut-finite-state-automata">
<span class="mathjax-exps">$\mathbf{Aut}$</span> (Finite state automata)</h4>
<ul>
<li>
<p>Objects: Finite state automata <span class="mathjax-exps">$(Q, \Sigma, \delta, q_0, F), (Q', \Sigma, \delta', q'_0, F')$</span></p>
<ul>
<li>
<span class="mathjax-exps">$Q$</span> is the set of states</li>
<li>
<span class="mathjax-exps">$\Sigma$</span> is the input alphabet</li>
<li>
<span class="mathjax-exps">$\delta : \Sigma \times Q \rightarrow Q$</span> is a transition map</li>
<li>
<span class="mathjax-exps">$q_0\in Q$</span> is the initial state</li>
<li>
<span class="mathjax-exps">$F \subseteq Q$</span> is the set of final/accepting states</li>
</ul>
</li>
<li>
<p>Morphisms: Simulations <span class="mathjax-exps">$f: Q \rightarrow Q'$</span> such that</p>
<ul>
<li>
<span class="mathjax-exps">$\forall \sigma\in\Sigma, \forall q\in Q, ~ f(\delta(\sigma, q)) = \delta'(\sigma, f(q))$</span>
<ul>
<li>(Transitions are preserved)</li>
</ul>
</li>
<li>
<span class="mathjax-exps">$f(q_0) = {q'}_0$</span>
<ul>
<li>(Initial states are mapped to each other)</li>
</ul>
</li>
<li>
<span class="mathjax-exps">$f(F) \subseteq F'$</span>
<ul>
<li>(Accepting states are preserved)</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Isomorphisms: Bijective simulations that are also bijective on the underlying sets. Note that this forces <span class="mathjax-exps">$g=f^{-1}: Q' \rightarrow Q$</span> to exist, and</p>
<ul>
<li>
<span class="mathjax-exps">$\forall \sigma\in\Sigma,~\forall q\in Q, (g\circ f)(\delta(\sigma, q)) = \delta(\sigma, q)$</span>, so <span class="mathjax-exps">$g\circ f = id_Q$</span>. Similarly, <span class="mathjax-exps">$f\circ g = Id_{Q'}$</span>
</li>
<li><span class="mathjax-exps">$q_0 = q'_0$</span></li>
<li><span class="mathjax-exps">$F = F'$</span></li>
</ul>
</li>
</ul>
<h4 class="mume-header" id="mathbfgraph"><span class="mathjax-exps">$\mathbf{Graph}$</span></h4>
<ul>
<li>
<p>Objects: Graphs <span class="mathjax-exps">$G = (V_1, E_2), H =(V_2, E_2)$</span> where <span class="mathjax-exps">$E_i \subseteq V_i\times V_i$</span></p>
</li>
<li>
<p>Morphisms: maps <span class="mathjax-exps">$f: V_1 \rightarrow V_2$</span> where <span class="mathjax-exps">$(v,w) \in E_1 \Rightarrow (f(v), f(w)) \in E_2$</span></p>
<ul>
<li>i.e. maps between vertex sets that preserve incidence relations.</li>
</ul>
</li>
<li>
<p>Isomorphisms: Bijective graph morphisms</p>
</li>
<li>
<p><span class="mathjax-exps">$\mathbf{Mat(\mathbb{F})}$</span></p>
<ul>
<li>Objects: Natural numbers <span class="mathjax-exps">$m, n$</span>
</li>
<li>Morphisms: <span class="mathjax-exps">$A:m \rightarrow n$</span> is <span class="mathjax-exps">$m\times n$</span> matrix with entries in the underlying field <span class="mathjax-exps">$\mathbb{F}$</span>
</li>
<li>Isomorphisms: Natural numbers <span class="mathjax-exps">$m, n$</span> for which there exists a <span class="mathjax-exps">$B: n\rightarrow m$</span> , i.e an <span class="mathjax-exps">$n\times m$</span> matrix, such that <span class="mathjax-exps">$AB = BA =I$</span>
<ul>
<li>Note that this can only possibly happen when <span class="mathjax-exps">$n=m$</span>, so <span class="mathjax-exps">$A,B$</span> are square. But then we can <em>always</em> just take the identity matrix <span class="mathjax-exps">$I_n = I_n^{-1}$</span> So isomorphisms are just equalities of natural numbers.</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: This category is a little different – the objects don’t matter much, since they’re really just keeping tracks of matrix dimensions. Instead, the morphisms themselves are the data this category encodes.</p>
<p>While this seems like an odd category to consider, the kicker is it’s possible to prove that there is a "full, faithful, surjective functor from <span class="mathjax-exps">$\mathbf{Mat}(\mathbb{F})$</span> to <span class="mathjax-exps">$\mathbf{Vec}(\mathbb{F})$</span>" – in other words, one can move between these categories without losing any vital information. In this case, this tells us that when working with (finite dimensional) vector spaces, it doesn’t matter whether you study abstract linear maps or the matrices that represent them!</p>
</li>
</ul>
<h4 class="mume-header" id="mathbfhask-pseudo-category">
<span class="mathjax-exps">$\mathbf{Hask}$</span> (pseudo-category)</h4>
<ul>
<li>Objects: Haskell types <span class="mathjax-exps">$A, B$</span>
</li>
<li>Morphisms: Functions <span class="mathjax-exps">$f: A \rightarrow B$</span>
</li>
<li>Isomorphisms: Type <span class="mathjax-exps">$A,B$</span> for which there exist functions <span class="mathjax-exps">$f: A\rightarrow B, g: B \rightarrow A$</span> such that <span class="mathjax-exps">$f.g b = id ~b$</span> and <span class="mathjax-exps">$g.f a = id ~a$</span>
<ul>
<li>Note: From the compiler’s point of view, <em>function</em> equivalence is perhaps the more interesting/important thing to look at!</li>
</ul>
</li>
</ul>
<h4 class="mume-header" id="mathbflambda-calc"><span class="mathjax-exps">$\mathbf{\lambda-Calc}$</span></h4>
<ul>
<li>Objects: Typed lambda calculi</li>
<li>Morphisms: Translations that map types to types, terms to terms, and preserve equations (<span class="mathjax-exps">$\alpha$</span> conversions, <span class="mathjax-exps">$\beta$</span> reductions, etc)</li>
</ul>
<h4 class="mume-header" id="mathbfdiff"><span class="mathjax-exps">$\mathbf{Diff}$</span></h4>
<ul>
<li>Objects: Smooth manifolds <span class="mathjax-exps">$(\mathcal{M}, \mathcal{A})$</span> ,where <span class="mathjax-exps">$\mathcal{M}$</span> is a topological manifold (locally homeomorphic to <span class="mathjax-exps">$\mathbb{R}^n$</span>), and <span class="mathjax-exps">$\mathcal{A}$</span> is a maximal smooth atlas on <span class="mathjax-exps">$\mathcal{M}$</span>.</li>
<li>Morphisms: Smooth maps <span class="mathjax-exps">$F: (\mathcal{M_1}, \mathcal{A_1}) \rightarrow (\mathcal{M_2}, \mathcal{A_2})$</span> (where <span class="mathjax-exps">$F = (f_1, f_2, \cdots)$</span>) such that <span class="mathjax-exps">$\frac{\partial f_i}{\partial x_j}$</span> is continuous for all <span class="mathjax-exps">$i,j$</span>, and if <span class="mathjax-exps">$\phi \in \mathcal{A_1}$</span> is a chart on <span class="mathjax-exps">$\mathcal{M_1}$</span>, then <span class="mathjax-exps">$F(\phi)\in\mathcal{A_2}$</span> and is a chart on <span class="mathjax-exps">$\mathcal{M_2}$</span>
</li>
<li>Isomorphisms: Diffeomorphisms, which are morphisms <span class="mathjax-exps">$F$</span> with a smooth inverse <span class="mathjax-exps">$G$</span>.</li>
</ul>
<p><em>Notes</em>: This is where differential geometry and a fair amount of topology takes places, as well as certain branches of analysis, partial differential equations, and physics.</p>
<h4 class="mume-header" id="mathbfmeas"><span class="mathjax-exps">$\mathbf{Meas}$</span></h4>
<ul>
<li>
<p>Objects: Measurable spaces <span class="mathjax-exps">$(X, \mathcal{\Sigma}_X), (Y, \mathcal{\Sigma}_Y)$</span></p>
<ul>
<li>(Where the <span class="mathjax-exps">$\Sigma \subset 2^X$</span> are <span class="mathjax-exps">$\sigma$</span>-algebras over their respective sets, and the members of <span class="mathjax-exps">$\Sigma$</span> are denoted the measurable sets)</li>
<li>Note that these are measur<strong>able</strong> spaces, not measure spaces – this is a space for which a measure <span class="mathjax-exps">$\mu$</span> can be assigned. The triple <span class="mathjax-exps">$(X, \Sigma, \mu_X)$</span> would be a <strong>measure</strong> space.</li>
</ul>
</li>
<li>
<p>Morphisms: Measurable functions <span class="mathjax-exps">$f: (X, \Sigma_X) \rightarrow (Y, \Sigma_Y)$</span> such that<br />
<span class="mathjax-exps">$E \in \Sigma_Y \Rightarrow f^{-1}(E) \in \Sigma_X$</span></p>
<p>(Where <span class="mathjax-exps">$f^{-1}$</span>denotes the preimage or pullback of <span class="mathjax-exps">$f$</span>)</p>
</li>
<li>
<p>Isomorphisms: Measurable functions <span class="mathjax-exps">$f$</span> with measurable inverses <span class="mathjax-exps">$g: (Y, \Sigma_Y) \rightarrow (X, \Sigma_X)$</span> where <span class="mathjax-exps">$F \in \Sigma_X \Rightarrow g^{-1}(F) \in \Sigma_Y$</span></p>
</li>
</ul>
<p><em>Notes</em>: This is where probability theory happens.</p>
<p>Also, it turns out to actually be very tricky to formulate measure theory in a categorical way! If we try to look at the category of <strong>measure</strong> spaces, it turns out that adding the actual measure <span class="mathjax-exps">$\mu$</span> to a measurable space is in some sense "too strong" of a condition, and the resulting category lacks many useful properties.</p>
<p>(In particular, it occludes the possibility of having a structure that is denoted the “categorical product”. Attempts formalize measure/probability in categorical terms is a topic of relatively current research.)</p>
<h4 class="mume-header" id="mathbftop"><span class="mathjax-exps">$\mathbf{Top}$</span></h4>
<ul>
<li>Objects: Topological Spaces <span class="mathjax-exps">$(X, \mathcal{T}_X)$</span>
</li>
<li>Morphisms: Continuous functions <span class="mathjax-exps">$f: (X, \mathcal{T}_X) \rightarrow (Y, \mathcal{T}_Y)$</span> such that if <span class="mathjax-exps">$U$</span> is open in <span class="mathjax-exps">$Y$</span>, then <span class="mathjax-exps">$f^{-1}(U)$</span> is open in <span class="mathjax-exps">$X$</span>.
<ul>
<li>Note that this is equivalent to <span class="mathjax-exps">$U \in \mathcal{T}_Y \Rightarrow f^{-1}(U) \in \mathcal{T}_X$</span>
</li>
</ul>
</li>
<li>Isomorphisms: Homeomorphisms where <span class="mathjax-exps">$f$</span> has an inverse <span class="mathjax-exps">$g$</span> (as in <span class="mathjax-exps">$\mathbf{Set}$</span>) where <span class="mathjax-exps">$g$</span> is also a continuous function.</li>
</ul>
<h4 class="mume-header" id="mathbfunif"><span class="mathjax-exps">$\mathbf{Unif}$</span></h4>
<ul>
<li>Objects: Uniform Spaces <span class="mathjax-exps">$(X, \varepsilon)$</span>
</li>
<li>Morphisms: Uniformly continuous maps</li>
<li>Isomorphisms: Uniform maps, i.e. uniformly continuous maps admitting a uniformly continuous inverse.
<ul>
<li>These can be thought of as homeomorphisms, along with an added condition of uniformity on the maps and their inverses.</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: A uniform space is a topological space, equipped with some notion of "<span class="mathjax-exps">$\varepsilon$</span>-closeness". Things like metric spaces and topological groups fit this description, so most analysis technically happens in this category.</p>
<h4 class="mume-header" id="mathbfmet"><span class="mathjax-exps">$\mathbf{Met}$</span></h4>
<ul>
<li>Objects: Metric spaces <span class="mathjax-exps">$(M_1, d_1), (M_2, d_2)$</span>
<ul>
<li>
<span class="mathjax-exps">$d_1 : M_1 \times M_1 \rightarrow \mathbb{R}$</span> is denoted the <em>metric</em> on <span class="mathjax-exps">$M_1$</span>.</li>
</ul>
</li>
<li>Morphisms: Contractions <span class="mathjax-exps">$f: (M_1, d_1) \rightarrow (M_2, d_2)$</span> such that <span class="mathjax-exps">$\forall x,y \in M_1$</span>, we have <span class="mathjax-exps">$d_2(f(x), f(y)) \leq d_1(x,y)$</span>.</li>
<li>Isomorphisms: Isometries
<ul>
<li>These are just the bijective contractions <span class="mathjax-exps">$f$</span>, so that <span class="mathjax-exps">$d_2(f(x), f(y)) = d_1(x,y)$</span>
</li>
</ul>
</li>
</ul>
<p><em>Notes</em>: The distance function <span class="mathjax-exps">$d$</span> has to satisfy a few more axioms than <span class="mathjax-exps">$\varepsilon$</span> in <span class="mathjax-exps">$\mathbf{Unif}$</span></p>
<p>Starting here, there are actually many choices we could make for the morphisms – for example, we could have chosen uniformly continuous functions, Lipschitz functions, or a few others. Here I’ve just chosen one of the weaker conditions – Lipschitz functions with constant 1.</p>
<p>Since every metric space is a topological space, the morphisms here need to extend the morphisms on <span class="mathjax-exps">$\mathbb{Top}$</span>. This is in fact the case in <span class="mathjax-exps">$\mathbf{Met}$</span>, since contractions on metric spaces end up being continuous.</p>
<h4 class="mume-header" id="mathbfnorm"><span class="mathjax-exps">$\mathbf{Norm}$</span></h4>
<ul>
<li>Objects: Normed spaces</li>
<li>Morphisms: Continuous and linear maps
<ul>
<li>i.e., <span class="mathjax-exps">$Hom(\mathbf{Met}) \cap Hom(\mathbf{Vec})$</span>
</li>
</ul>
</li>
<li>Isomorphisms: Continuous linear bijective maps with continuous linear inverses</li>
</ul>
<h4 class="mume-header" id="mathbfban-complete-normed-vector-spaces">
<span class="mathjax-exps">$\mathbf{Ban}$</span> (Complete normed vector spaces)</h4>
<ul>
<li>Objects: Banach spaces <span class="mathjax-exps">$B, C$</span>
</li>
<li>Morphisms: Bounded linear maps <span class="mathjax-exps">$f: B \rightarrow C$</span> such that <span class="mathjax-exps">$\Vert f\Vert_{\text{sup}}$</span> is finite.
<ul>
<li>If <span class="mathjax-exps">$B=C$</span>, these are usually referred to as <em>bounded linear operators</em>
</li>
</ul>
</li>
<li>Isomorphisms: Bijective bounded linear maps with bounded linear inverses.</li>
</ul>
<p><em>Notes</em>: A Banach space is a vector space that is also a complete metric space, so the morphisms simply reflect that these two structures “play nicely” together. This is the case, since the following three are equivalent in Banach spaces:</p>
<ul>
<li>Bounded linear maps</li>
<li>Continuous linear maps</li>
<li>Uniformly continuous linear maps</li>
</ul>
<p>This is also where much of functional analysis happens.</p>
<h4 class="mume-header" id="mathbfhilb-complete-inner-product-spaces">
<span class="mathjax-exps">$\mathbf{Hilb}$</span> (Complete inner product spaces)</h4>
<ul>
<li>Objects: Hilbert Spaces <span class="mathjax-exps">$\mathcal{H}, \mathcal{K}$</span>
</li>
<li>Morphisms: Bounded linear maps <span class="mathjax-exps">$T: \mathcal{H} \rightarrow \mathcal{K}$</span> such that <span class="mathjax-exps">$\Vert T \Vert_{sup}$</span> is finite.</li>
<li>Isomorphisms: Bounded linear maps with bounded linear inverses.</li>
</ul>
<p><em>Notes</em>: It might seem a bit simplistic at first to characterize something like a Hilbert space as essentially an “enriched vector space”, but this turns out to be reflected in its categorical structure – the forgetful functor from <span class="mathjax-exps">$\mathbf{Hilb}$</span> to <span class="mathjax-exps">$\mathbf{Vec}$</span> given by forgetting the inner product is <strong>faithful</strong> (the categorical analog of "surjective" for normal functions)</p>
<p>Similarly, one can simultaneously regard any Hilbert space as a Banach space, where the norm is induced by the inner product.</p>
<h4 class="mume-header" id="mathbfcat"><span class="mathjax-exps">$\mathbf{Cat}$</span></h4>
<ul>
<li>Objects: Small categories <span class="mathjax-exps">$C = (Ob(C), Hom(C)), ~D = (Ob(D), Hom(D))$</span>
</li>
<li>Morphisms: <strong>Functors</strong> <span class="mathjax-exps">$F: (Ob(C), Hom(C)) \rightarrow (Ob(D), Hom(D))$</span>
<ul>
<li>Functors map:
<ul>
<li>objects <span class="mathjax-exps">$c, c' \in Ob(C)$</span> to objects <span class="mathjax-exps">$F(c) = d, F(c') = d' \in Ob(D)$</span>,</li>
<li>morphisms <span class="mathjax-exps">$f:c \rightarrow c' \in Hom_C(c, c')$</span> to morphisms <span class="mathjax-exps">$F(f) : F(c) \rightarrow F(c') \in Hom_D(F(c), F(c'))$</span>,
<ul>
<li>Or to clean up notation a bit, morphisms that look like <span class="mathjax-exps">$g: d \rightarrow d' \in Hom(d, d')$</span>.</li>
</ul>
</li>
</ul>
</li>
<li>In words, this just sends the objects and arrows of one category to another, preserving the way arrows connect objects</li>
</ul>
</li>
<li>Isomorphisms: <strong>Natural isomorphisms</strong>, i.e. functors <span class="mathjax-exps">$F: C \rightarrow D$</span> with a dual functor <span class="mathjax-exps">$G: D \rightarrow C$</span> such that <span class="mathjax-exps">$F \circ G \cong Id_D \text{ and } G \circ F \cong Id_C$</span>
</li>
</ul>
<h2 class="mume-header" id="building-more-examples">Building More Examples</h2>
<p>We can also make simple modifications to existing categories to obtain new ones:</p>
<ul>
<li>Denote a “distinguished” point : yields pointed categories (e.g. manifolds with base points)</li>
<li>Add structural restrictions to get “smaller” categories
<ul>
<li>Force commutativity
<ul>
<li><span class="mathjax-exps">$\mathbf{Ab} \injects \mathbf{Grp}$</span></li>
<li><span class="mathjax-exps">$\mathbf{CRing} \injects \mathbf{Ring}$</span></li>
</ul>
</li>
<li>Forget some structure
<ul>
<li>
<span class="mathjax-exps">$\mathbf{Ring}\rightarrow \mathbf{Grp}$</span>
<ul>
<li>(Just forget about multiplication)</li>
</ul>
</li>
</ul>
</li>
<li>Equip the objects with more structure and/or supply more stringent morphisms
<ul>
<li>
<span class="mathjax-exps">$\mathbf{Top} \surjects \mathbf{Diff}$</span>
<ul>
<li>Require that the continuous maps be differentiable</li>
</ul>
</li>
<li>
<span class="mathjax-exps">$\mathbf{Set} \surjects \mathbf{FinSet}$</span>
<ul>
<li>Require the cardinality of the sets to be finite (This is where combinatorics is done)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>“Parameterized” categories
<ul>
<li>
<span class="mathjax-exps">$\mathbf{Vect_k}$</span> where <span class="mathjax-exps">$k \in \{ \mathbb{R}, \mathbb{C}, \ZZ_{p}, \cdots\} is a field$</span>
</li>
<li>
<span class="mathjax-exps">$\mathbf{C^A}$</span>: the category whose objects are morphisms in a fixed category <span class="mathjax-exps">$C$</span> with source <span class="mathjax-exps">$A$</span> (This can be thought of as a category of commutative diagrams involving <span class="mathjax-exps">$\mathbf{A}$</span>)</li>
</ul>
</li>
<li>The category of all morphisms in a fixed category <span class="mathjax-exps">$\mathbf{C}$</span>, which yields <span class="mathjax-exps">$n\dash$</span>categories.</li>
<li>Take <span class="mathjax-exps">$C$</span> and reverse arrows to obtain <span class="mathjax-exps">$C^{op}$</span> to obtain a form of "duality".</li>
</ul>
<p><-- #TODO --></p>
<h1 class="mume-header" id="big-ideas">Big Ideas</h1>
<ul>
<li>Duality</li>
<li>Isomorphisms</li>
<li>Universal Properties
<ul>
<li>Build new objects out of old ones, or “factor” objects into smaller ones</li>
<li>Define things “up to a unique isomorphism”</li>
<li>Yoneda’s Lemma: To study an object, just look at the maps into and/or out of it!</li>
</ul>
</li>
<li>Functors</li>
<li>Limits / Colimits
<ul>
<li>Limits: Build new objects by “imposing equations” on existing ones.
<ul>
<li>Ex: Construction of the p-adic integers as the limit of the sequence of quotient homomorphisms: <span class="mathjax-exps">$\cdots \rightarrow \mathbb{Z}/p^n \rightarrow \cdots \rightarrow \mathbb{Z}/p^2 \rightarrow \mathbb{Z}/p$</span>
</li>
</ul>
</li>
<li>Colimits: Build new objects by “gluing together” existing ones:</li>
<li>Examples:
<ul>
<li>Products</li>
<li>Quotients</li>
<li>Kernels</li>
<li>Completions</li>
<li>Free products</li>
</ul>
</li>
</ul>
</li>
<li>Adjunction
<ul>
<li>Duality between functors</li>
<li>“Partial equivalence” of categories</li>
</ul>
</li>
<li>Kan Extensions</li>
</ul>
<h2 class="mume-header" id="duality">Duality</h2>
<ul>
<li>Reverse arrows and redefine composition in <span class="mathjax-exps">$C$</span> to obtain <span class="mathjax-exps">$C^{op}$</span>
</li>
<li>Then every “thing” in <span class="mathjax-exps">$C$</span> has a corresponding "thing" in <span class="mathjax-exps">$C^{op}$</span>, which we call a co-"thing".
<ul>
<li>Products and Coproducts</li>
<li>Kernels and Cokernels</li>
<li>Limits and Colimits</li>
</ul>
</li>
<li>Can often obtain two conclusions for the price of one!</li>
<li>Duality is an involution
<ul>
<li>i.e., a co-co-<span class="mathjax-exps">$X$</span> is just an <span class="mathjax-exps">$X$</span>
</li>
</ul>
</li>
<li>Canonical Example: Vector spaces <span class="mathjax-exps">$V$</span> and their duals <span class="mathjax-exps">$V^*$</span> over a field <span class="mathjax-exps">$k$</span>
<ul>
<li>
<span class="mathjax-exps">$V^* = \{\phi: V \rightarrow k\}$</span> where <span class="mathjax-exps">$\phi$</span> is linear</li>
<li>
<span class="mathjax-exps">$V \not\cong V*$</span>, but <span class="mathjax-exps">$V \cong V^{**}$</span>
</li>
</ul>
</li>
<li>Very powerful! Example: Poincare Duality
<ul>
<li>The <span class="mathjax-exps">$k$</span>th homology group of an <span class="mathjax-exps">$n$</span>-dimensional manifold is isomorphic <span class="mathjax-exps">$(n-k)$</span>th cohomology group</li>
<li>
<span class="mathjax-exps">$H^k(M) \cong H_{n-k}(M)$</span>.</li>
</ul>
</li>
</ul>
<h2 class="mume-header" id="universal-properties">Universal Properties</h2>
<p>For another time!</p>
</div>D. Zack Garzadzackgarza@gmail.comA relatively short introduction to Category Theory, including some concrete examples.Setting Up A Haskell Dev Environment2015-05-30T00:00:00-07:002015-05-30T00:00:00-07:00https://dzackgarza.com/tutorials/setting-up-a-haskell-dev-environment<p>Since the second week of this year’s GSOC is drawing to a close, I figured I’d
take a minute to write a bit about my experience diving into Haskell
development.</p>
<p>As someone relatively new to the Haskell world, I’ve had quite a bit to
learn - fortunately, there’s pleny of documentation out there, and the IRC
community is incredibly helpful as well (particularly #haskell, #hackage,
and #haskell-beginners on Freenode).</p>
<p>However, the packaging and build tools themselves are in constant development,
and working with cabal can be a bit tricky at first. In particular, there’s a
lot of noise in forums and wikis concerning the best way to source your
haskell packages - at this point, there are at several separate, viable
ways to manage them:</p>
<ul>
<li>
<p>Use the Haskell packages provided by your distro’s package manager,</p>
</li>
<li>
<p>Install cabal from your distro’s package manager, use it to bootstrap
cabal-install, then pull and build packages from hackage using
<code class="highlighter-rouge">cabal install <package_name></code>.</p>
</li>
<li>
<p>Clone repos from git or darcs directly, and create binaries using
<code class="highlighter-rouge">cabal install</code> in the project’s root directory (preferably using sandboxes), or</p>
</li>
<li>
<p>Use one another tool to help streamline the process, such as the
Nix package manager or Halcyon.</p>
</li>
</ul>
<p>Personally, I’ve run into issues with some of these methods. I work across
three different operating systems (Debian, Arch, and Windows), and coordinating
equivalent packages can be tedious at best.
Bootstrapping cabal-install can very quickly lead to the infamous “cabal hell”,
in which it becomes difficult to keep track of exactly which packages are
sourced as dependencies when you build something new. Cloning repos manually
works fairly well, but in this case it’s difficult to install system-wide tools
that rely on GHC such as HLint, ghc-mod, hdevtools, or really any other package
that’s compiled against the GHC API.</p>
<p>For these reasons, I decided to combine approaches 3 and 4 to set up a
reliable and easily reproducible dev environment – I rely on the package
manager to provide an up-to-date version of GHC for building packages from
source, and have a global config using halcyon that I can switch into with a
few commands for doing dev work.</p>
<p>There are some pretty nice benefits to doing things this way - for example, I
use the haskell-based xmonad for my window manager. With this setup, I can
compile my configuration against the newest version of GHC, and not have to
worry about one of its dependencies clobbering another project’s dependencies
or having to roll back my global version of GHC to install older packages.</p>
<p>Overall, it’s proved so far to be a great way to keep dependencies cleanly
separated, while still allowing multiple versions of ghc and cabal to be
installed alongside each other. Setting things up is pretty straightforward, so
here’s a quick rundown of what you can do to quickly get a dev environment
rolling.</p>
<h1 id="install-halycon">Install Halycon</h1>
<p>In my case, it was easiest to start with a clean OS installation. Assuming
you’re using a *nix variant, the steps should be roughly similar.</p>
<p>Start by installing halcyon – in my case, I did so as root to simplify things.
You can find a tutorial over at <a href="https://halcyon.sh/tutorial/">https://halcyon.sh/tutorial/</a>, but the key bit
is to run:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">eval</span> <span class="s2">"</span><span class="k">$(</span> curl <span class="nt">-sL</span> https://github.com/mietek/halcyon/raw/master/setup.sh <span class="k">)</span><span class="s2">"</span></code></pre></figure>
<p>and check that <code class="highlighter-rouge">which ghc</code> and <code class="highlighter-rouge">which cabal</code> both return paths in the /app/
directory.</p>
<p>From this point on, any user with access to the /app/ directory can call
<code class="highlighter-rouge">eval "$( /app/halcyon/halcyon paths</code> )”` to jump into this environment - this
command takes care of putting the correct versions of ghc and cabal at the
front of your path, regardless of which versions you may have otherwise
installed elsewhere.</p>
<p>You can then use <code class="highlighter-rouge">halcyon install</code> in place of <code class="highlighter-rouge">cabal install</code>
to ensure that your packages are built against the particular versions of ghc
and cabal you just installed.</p>
<h1 id="grab-some-dev-tools">Grab Some Dev Tools</h1>
<p>In particular, if you’re doing development with these versions, you’ll want to
build any tools that require executables using halcyon – here are a few
examples to get you started:</p>
<h3 id="ghc-mod-httpshackagehaskellorgpackageghc-mod"><strong>ghc-mod</strong> (<a href="https://hackage.haskell.org/package/ghc-mod">https://hackage.haskell.org/package/ghc-mod</a>)</h3>
<p>Provides vim/emacs integration for type checking, linting, and showing compiler
errors. Pairs really well with <strong>ghcmod-vim</strong>
(<a href="https://github.com/eagletmt/ghcmod-vim">https://github.com/eagletmt/ghcmod-vim</a>) and <strong>syntastic</strong>
(<a href="https://github.com/scrooloose/syntastic">https://github.com/scrooloose/syntastic</a>) for vim users.</p>
<h3 id="hasktags-httpshackagehaskellorgpackagehasktags"><strong>hasktags</strong> (<a href="https://hackage.haskell.org/package/hasktags">https://hackage.haskell.org/package/hasktags</a>)</h3>
<p>A ctags alternative for Haskell projects. Use this to generate a .tags file for
your project, and you can easily jump to function/type definitions using
Ctrl-].</p>
<h3 id="codex-httpshackagehaskellorgpackagecodex"><strong>codex</strong> (<a href="https://hackage.haskell.org/package/codex">https://hackage.haskell.org/package/codex</a>)</h3>
<p>Uses hasktags to build your entire tags database with a single command</p>
<ul>
<li><code class="highlighter-rouge">codex update</code>. What’s more, it also includes the tags of all of your
project’s dependencies – so if, for example, you run <code class="highlighter-rouge">cabal install</code>
inside of a sandbox, you can easily jump into the source code of
other libraries and see function definitions, types, etc.</li>
</ul>
<h3 id="hscope-httpshackagehaskellorgpackagehscope"><strong>hscope</strong> (<a href="https://hackage.haskell.org/package/hscope">https://hackage.haskell.org/package/hscope</a>)</h3>
<p>A cscope alternative for Haskell, which is kind of a reverse-direction ctags.
After generating a database, you can press Ctrl-\ on a function definition to
instantly find all of the places in your project that call that function.
Paired with hasktags, jumping through a new codebase is a breeze.</p>
<h3 id="hlint-httpshackagehaskellorgpackagehlint"><strong>hlint</strong> (<a href="https://hackage.haskell.org/package/hlint">https://hackage.haskell.org/package/hlint</a>)</h3>
<p>Quickly parses a file and provides suggestions for style improvement. Can also
be called using <strong>syntastic</strong> in vim (using :SyntasticCheck hlint).</p>
<h3 id="hoogle-httpshackagehaskellorgpackagehoogle"><strong>hoogle</strong> (<a href="https://hackage.haskell.org/package/hoogle">https://hackage.haskell.org/package/hoogle</a>)</h3>
<p>A Haskell-specific search engine, lets you quickly look up function type
signatures and definitions. Also has a neat feature that lets you search for
functions by type signature – for example, searching for
<code class="highlighter-rouge">(a->b)->[a]->[b]</code> brings up the map function and a few examples of how to use
it. Super handy!</p>
<p>If you install any or all of these using <code class="highlighter-rouge">halcyon install</code>, their binaries will
be placed in /app/bin/, and will be on your path any time you’re using
halcyon’s environment.</p>
<h1 id="get-text-editor-integration">Get Text Editor Integration</h1>
<p>After trying several IDEs and plugins, I found that using vim with a few choice
plugins netted me all of the features I really needed, and required the least
troubleshooting.</p>
<h2 id="the-necessities">The Necessities</h2>
<p>If you’re just looking to get started as soon as possible, look no further
than…</p>
<h3 id="haskell-vim-now-httpsgithubcombegriffshaskell-vim-now"><strong>haskell-vim-now</strong> (<a href="https://github.com/begriffs/haskell-vim-now">https://github.com/begriffs/haskell-vim-now</a>)</h3>
<p>It has an automated setup, and provides a ton of great Haskell-specific tools
right out of the box. (See the readme for the default key bindings.)</p>
<p>However, if you’re like me and already have a ridiculously long vimrc built up,
take a look following repos for some useful plugins:</p>
<h3 id="syntastic-httpsgithubcomscrooloosesyntastic"><strong>syntastic</strong> (<a href="https://github.com/scrooloose/syntastic">https://github.com/scrooloose/syntastic</a>)</h3>
<p>Easily the plugin I use the most, and derive the most value from. If you have
the ghc-mod binary on your path (which would be the case if you ran the eval
command from earlier), then you can easily check your current file. With a few
mappings like</p>
<figure class="highlight"><pre><code class="language-vim" data-lang="vim">map <span class="p"><</span><span class="k">silent</span><span class="p">></span> <span class="p"><</span>leader<span class="p">></span>hc <span class="p">:</span>SyntasticCheck<span class="p"><</span>CR<span class="p">></span>
map <span class="p"><</span><span class="k">silent</span><span class="p">></span> <span class="p"><</span>leader<span class="p">></span>hl <span class="p">:</span>SyntasticCheck hlint<span class="p"><</span>CR<span class="p">></span></code></pre></figure>
<p>, you can quickly get line markers and status messages for any errors. This
also works within projects quite well, and will only recompile files that
have changed since the last build (note: this can still be a bit slow for large
projects).</p>
<h3 id="ghcmod-vim-httpsgithubcomeagletmtghcmod-vim"><strong>ghcmod-vim</strong> (<a href="https://github.com/eagletmt/ghcmod-vim">https://github.com/eagletmt/ghcmod-vim</a>)</h3>
<p>Can also perform type checking and linting, but one of its most useful features
is the ability to display the type of an expression under the cursor by calling
<code class="highlighter-rouge">:GhcModType</code>, or to pull up info about its definition with <code class="highlighter-rouge">:GhcModInfo</code>.</p>
<h3 id="haskellmode-vim-httpsgithubcomlukerandallhaskellmode-vim"><strong>haskellmode-vim</strong> (<a href="https://github.com/lukerandall/haskellmode-vim">https://github.com/lukerandall/haskellmode-vim</a>)</h3>
<p>Mainly fixes up some extra syntax highlighting and indentation. Also offers a
few neat features like looking up the word under the cursor on hoogle, and
automatically adding qualified imports.</p>
<h3 id="vim-haskellconcealplus"><strong>vim-haskellConcealPlus</strong></h3>
<p>(<a href="https://github.com/enomsg/vim-haskellConcealPlus">https://github.com/enomsg/vim-haskellConcealPlus</a>)
This one’s purely aesthetic, and a great way to test exactly how well your
terminal emulator support UTF-8! Uses vim conceals to show some Haskell
operators and keywords as symbols (that is, it displays them as special symbols
unless they are on your current line). This is particularly useful when you’re
browing large swaths of code, and want to make things a bit more readable.
Note: this does need a small hack not to be a complete eyesore. By default, vim
adds a background highlight to every concealed character. You can clear this by
throwing</p>
<figure class="highlight"><pre><code class="language-vim" data-lang="vim"><span class="k">au</span> <span class="nb">FileType</span> haskell autocmd <span class="nb">VimEnter</span> * <span class="k">hi</span> <span class="k">clear</span> Conceal</code></pre></figure>
<p>into your vimrc.</p>
<h2 id="general-vim-goodness">General Vim Goodness</h2>
<p>Here are some other useful plugins (not Haskell-specific) for jumping around large projects include:</p>
<ul>
<li>
<p><strong>CtrlP</strong> (<a href="https://github.com/kien/ctrlp.vim">https://github.com/kien/ctrlp.vim</a>)
Open files with a fuzzy-finder.</p>
</li>
<li>
<p><strong>Ag</strong> (<a href="https://github.com/ervandew/ag">https://github.com/ervandew/ag</a>)
Fast replacement for vimgrep, quickly find specific words from files in your
current working tree.</p>
</li>
<li>
<p><strong>Supertab</strong> (<a href="https://github.com/ervandew/supertab">https://github.com/ervandew/supertab</a>)
Provides tab-completion - suggestion list can be populated from local buffer or
other plugins like neco-ghc.</p>
</li>
<li>
<p><strong>Fugitive</strong> (<a href="https://github.com/tpope/vim-fugitive">https://github.com/tpope/vim-fugitive</a>)
Provides most common git commands within vim.</p>
</li>
</ul>
<h1 id="workflow">Workflow</h1>
<p>Finally, the good part! Everything’s easy from here on out. With everything
installed, you can create a user and chown the /app/ directory. Then, you can
go about your day-to-day business with your package manager’s version of ghc
and cabal (just remember to run <code class="highlighter-rouge">cabal sandbox init</code> before building/installing
to keep things as clean as possible).</p>
<p>Then, whenever you’re working on a dev project, just call the eval statement
mentioned up in the halcyon section, and all of the binaries you installed with
halcyon will be on your path, all linked properly, and you’ll be using the same
versions of ghc and cabal each and every time.</p>
<p>Generally, before I start working on a project, I run a function that looks
something like this:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">git clone http://url/to/your/project ~/project_directory
<span class="nb">cd</span> ~/project_directory
<span class="nb">eval</span> <span class="s2">"</span><span class="k">$(</span> /app/halcyon/halcyon paths <span class="k">)</span><span class="s2">"</span>
cabal sandbox init
cabal <span class="nb">install
</span>cabal build</code></pre></figure>
<p>And there you have it! Hopefully this serves as a bit of help to anyone else
getting started with Haskell. Please feel free to leave any questions or
comments below!</p>D. Zack Garzadzackgarza@gmail.comSince the second week of this year’s GSOC is drawing to a close, I figured I’d take a minute to write a bit about my experience diving into Haskell development.Introductory Statistical Analysis in R2014-07-18T00:00:00-07:002014-07-18T00:00:00-07:00https://dzackgarza.com/introductory-statistical-analysis-in-r<p>This Summer, while I’ve been interning at Shutterfly, I’ve also been taking a course in introductory statistics. Of course, since I’m majoring in Computer Science, I’m always looking for new ways to tie computer science into whatever I happen to be learning. Fortunately, there is quite a bit of overlap between these fields, and there are many computational tools out there that make it easy to analyze data.</p>
<p>Since my calculator (a TI-92, for those of you that are into calculators!) doesn’t have very many statistical capabilities or build in programs, my tools of choice for this semester have been a combination of the statistics package <script type="math/tex">R</script>, as well as several programs I’ve written for my calculator in BASIC. <script type="math/tex">R</script> is free and open source, and can very likely be found in your package manager of choice. In this article, I hope to cover a few ways to use it to perform some basic analysis on data sets.</p>
<p>Once you have <script type="math/tex">R</script> installed, grab a data set and dive in!</p>
<h1 id="1-dimensional-data-sets">1-Dimensional Data Sets</h1>
<p>Let’s say you simply have a list of values, and you want to know some of its statistical properties - the mean, median, mode, and maybe even the different quartiles the values fall in to. The first order of business is to get your data into a file.</p>
<p>Doing everything from the command line makes things fairly straightforward. If you can copy your data onto the clipboard, you can easily pipe it into a file with xclip. If you don’t already have xclip installed, and you’re on a Debian variant, you can install it using</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">sudo </span>apt-get <span class="nb">install </span>xclip</code></pre></figure>
<p>Since xclip’s command-line options aren’t especially intuitive, it helps to make quick aliases for the copy and paste commands. You can use whatever you’d like - I went with ‘cpaste’ and ‘ccopy’ - and simply echo them into your .bashrc, .zshrc, or external alias file. Make sure to refresh your .rc file after adding them, though!</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="s2">"alias cpaste='xclip -selection clipboard -o'"</span> <span class="o">>></span> ~/.bashrc
<span class="nb">echo</span> <span class="s2">"alias ccopy='xclip -selection c'"</span> <span class="o">>></span> ~/.bashrc
<span class="nb">source</span> ~/.bashrc</code></pre></figure>
<p>Once you have this, you can then pipe your clipboard contents into a file.</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">cpaste <span class="o">></span> ~/data.csv</code></pre></figure>
<p>Great! So now we have a quick way of getting some data into a file. Next, we need to load it as a data frame in <script type="math/tex">R</script>. Lucky for us, there are already plenty of functions in place to accomplish this, so I’ll just demonstrate one. You can launch <script type="math/tex">R</script> by simply typing “R”, as long as it’s on your path.</p>
<figure class="highlight"><pre><code class="language-r" data-lang="r"><span class="c1"># Read in the data</span><span class="w">
</span><span class="n">t</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">read.csv</span><span class="p">(</span><span class="s2">"~/data.csv"</span><span class="p">,</span><span class="w"> </span><span class="n">header</span><span class="o">=</span><span class="kc">TRUE</span><span class="p">)</span><span class="w">
</span><span class="n">t</span><span class="w"> </span><span class="c1"># Display the contents of t - namely, the data we just read in.</span><span class="w">
</span><span class="n">tail</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="c1"># Display the last few entries of t</span><span class="w">
</span><span class="nf">length</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="c1"># Display how many entries t contains</span><span class="w">
</span><span class="n">summary</span><span class="p">(</span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="c1"># Get a quick overview</span></code></pre></figure>
<h1 id="scatterplots-and-linear-regression">Scatterplots and Linear Regression</h1>
<p>Of course, the whole point of using something like $R$ is because it makes it so easy to perform statistical analysis. So let’s dive right in!</p>
<figure class="highlight"><pre><code class="language-r" data-lang="r"><span class="n">plot</span><span class="p">(</span><span class="n">t</span><span class="o">$</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">t</span><span class="o">$</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="c1"># Produce a scatterplot of x vs. y</span><span class="w">
</span><span class="n">cor</span><span class="p">(</span><span class="n">t</span><span class="o">$</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">t</span><span class="o">$</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="c1"># Display the R value for linear correlations</span><span class="w">
</span><span class="n">fit</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">lm</span><span class="p">(</span><span class="n">formula</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">t</span><span class="o">$</span><span class="n">x</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="n">t</span><span class="o">$</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="c1"># Perform a linear regression, and store the result</span><span class="w">
</span><span class="n">fit</span><span class="w"> </span><span class="c1"># Display the slope and y-intercept the linear regression</span><span class="w">
</span><span class="n">summary</span><span class="p">(</span><span class="n">fit</span><span class="p">)</span><span class="w"> </span><span class="c1"># Display a more detailed analysis</span></code></pre></figure>
<h1 id="hypothesis-testing-with-multiple-populations">Hypothesis Testing with Multiple Populations</h1>
<p>To be continued!</p>D. Zack Garzadzackgarza@gmail.comThis Summer, while I’ve been interning at Shutterfly, I’ve also been taking a course in introductory statistics. Of course, since I’m majoring in Computer Science, I’m always looking for new ways to tie computer science into whatever I happen to be learning. Fortunately, there is quite a bit of overlap between these fields, and there are many computational tools out there that make it easy to analyze data.Big O Notation2014-05-31T00:00:00-07:002014-05-31T00:00:00-07:00https://dzackgarza.com/big-o-notation<p>Some quick notes on Big O notation.<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup></p>
<h1 id="how-to-determine-running-time-complexity">How to Determine Running-Time Complexity</h1>
<h2 id="nested-loops">Nested Loops</h2>
<p>Consider a general sequence of nested loops in which the outer loop is iterated <script type="math/tex">N</script> times and the inner loop is iterated <script type="math/tex">M</script> times. Generally, these will look something like this:</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">M</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//statements</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Every time the outer loop executes, the inner loop runs <script type="math/tex">M</script> times. Thus, we expect this function to run in <script type="math/tex">O(N \cdot M)</script>, or <script type="math/tex">O(N^2)</script> in the case that <script type="math/tex">N=M</script>.</p>
<p>A similar case arises when the inner loop depends on the outer loop. Consider the function</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="n">j</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o"><</span> <span class="n">N</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//statements</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Since the outer loop ranges over <script type="math/tex">% <![CDATA[
0<i<N-1 %]]></script>, while the inner loop ranges from <script type="math/tex">N>j>1</script>, the total number of operations is given by</p>
<p>\[ \sum_{i=1}^{N} i = \frac{N(N+1)}{2}\]</p>
<p>which is the sum of the first <script type="math/tex">N</script> natural numbers, and thus this function is also in <script type="math/tex">O(n^2)</script>.</p>
<h2 id="function-composition">Function Composition</h2>
<p>Consider a function <script type="math/tex">g(n) \in O(n)</script> for which the complexity depends on the number of inputs <script type="math/tex">n</script>.
If this function is embedded within another function <script type="math/tex">f(m) \in O(m)</script> that also depends on another variable <script type="math/tex">m</script>, then the composition <script type="math/tex">(f \circ g) \in O(n \cdot m)</script>.</p>
<p>Again, in the special case that <script type="math/tex">n=m</script>, then <script type="math/tex">(f \circ g) \in O(n^2)</script>.</p>
<p>For example, take <script type="math/tex">f</script> to be a loop, and <script type="math/tex">g</script> to be a function called within the loop. Then you wind up with something like this:</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"> <span class="kt">void</span> <span class="n">f</span><span class="p">(</span><span class="n">n</span><span class="p">)</span><span class="o">:</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">g</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></figure>
<p>The loop iterates <script type="math/tex">n</script> times, and <script type="math/tex">g</script> is called each time. So we have an overall complexity of <script type="math/tex">O(n \cdot n) \in O(n^2)</script>.</p>
<p>Note: This method may not always produce the tightest upper bound possible. For more specific cases, tighter bounds on running time can be found by considering the total time spent on the inner loop and outer loop separately, and adding them.</p>
<hr />
<p>That’s all for today’s post, although I may end up adding more information later! If you have any questions or found this helpful, feel free to comment below.</p>
<hr />
<h1 id="links-and-references">Links and References</h1>
<p><a href="http://ozark.hendrix.edu/~burch/cs/280/work/r1/print.html">Some great practice problems and explanations: Carl Burch at Hendrix</a></p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p><a href="http://pages.cs.wisc.edu/~vernon/cs367/notes/3.COMPLEXITY.html#application">Notes on complexity: Mary K. Vernon at U. Wisconsin</a> <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>D. Zack Garzadzackgarza@gmail.comDetermining the running-time complexity of some common types of functions.