Hacker News new | ask | show | jobs
by tommikaikkonen 3358 days ago
I've applied the Monoid and Semigroup patterns often in Python and JS. Knowing about CT helps you leverage their properties (associativity, often commutativity, having an explicit identity element for a monoidal operation), and writing tests against those properties.

They're common patterns a lot of people use without knowing anything about CT, for example if you fold/reduce over a collection with an initial value, and the collection may be empty, you're looking at a monoidal operation. You can call the initial value a constant identity. Like sum, product.

If you fold/reduce over a collection where the collection may not be empty, and you need to use the first element as the initial value, you're looking at a semigroup operation. Like min/max/mean.

1 comments

Applying semigroup in JavaScript is a wholly different enterprise than studying adjunctions, pullbacks, and the Yoneda lemma. I know we programmers like to call using Monoids "CT", to smash Things together with some associativity (those things existed in abstract algebra long before CT), but I don't think those things capture what CT is about or what the OP article is investigating.
So after looking into Category Theory for a bit, it seems like everything CT that most people use (and I had wanted to learn) is covered in abstract algebra. Monoid / Semi-groups, algebraic properties. And an in an easier presentation than CT.

What are some programming applicable Category Theory topics that aren't covered in abstract algebra?

Monads.
Not to be pedantic, but if someone understands monoids well from abstract algebra and someone else says:

"By the way, in addition to all the existing monoids you know (Ints under '+', strings, lists...), functions under function composition also form a monoid. Here's an example."

Isn't that pretty much getting them to the same place? Do they really need a study of category theory?

Function composition is a monoid, but it is not a monad, even though the words sound similar. So it's not really getting them to the same place, but I'm not going to offer any opinion on whether someone needs to study category theory.

Not quite function composition, but given a type a, (a ->) is a monad (the so called "reader monad"). We have

   return :: x -> (a -> x)
   return x = \a -> x
   
   (>>=) :: (a -> x) -> (x -> (a -> y)) -> (a -> y)
   m >>= f  = \a -> f (m a) a
(Incidentally, these are two of the Łukasiewicz axioms for propositional calculus.)

It is a functor with

   fmap :: (x -> y) -> (a -> x) -> (a -> y)
   fmap f m = \a -> f (m a)
In the case x=y, then fmap takes the monoid of functions on x to the monoid of functions on (a -> x).

Venturing into more abstract territory, "a monad is a monoid in the category of endofunctors of a category C." (This has never helped me with understanding how to use monads in Haskell.) Basically, the choice of endofunctor is the type constructor for the monad, the unit map is `return` and the composition map is `join`.

> return :: x -> (a -> x)

> return x = \a -> x

>

> (>>=) :: (a -> x) -> (x -> (a -> y)) -> (a -> y)

> m >>= f = \a -> f (m a) a

>(Incidentally, these are two of the Łukasiewicz axioms for propositional calculus.)

Also the K and S in SKI combinator calculus https://en.wikipedia.org/wiki/SKI_combinator_calculus

Isn't the identity monad isomorphic to normal functions? In that sense normal functions are a monad.
Functions of type A -> A for some A form a monoid under composition, but functions of arbitrary type don't. The nifty phrase "a monad is just a monoid in the category of endofunctors" doesn't refer to the function composition monoid, but something much stranger, where the "composition" operation has type m (m a) -> m a, and the "identity" operation has type a -> m a. To understand how that can be seen as a monoid, note that the composition operation composes two effects on the same computation, and the identity operation adds an empty effect.
> note that the composition operation composes two effects on the same computation, and the identity operation adds an empty effect.

Thanks - While I did have this vague idea, and it says it from the types, seeing it written out in this way was clarifying.