6

I've been doing some light reading on functional programming concepts and ideas. So far, so good, I've read about three main concepts: algebraic structures, type classes, and algebraic data types. I have a fairly good understanding of what algebraic data types are. I think sum types and product types are fairly straightforward. For example, I can imagine creating an algebraic data type like a Card type which is a product type consisting of two enum types, Suit (with four values and symbols) and Rank (with 13 values and symbols).

However, I'm still hung up on trying to understand precisely what algebraic structures and type classes are. I just have a surface-level picture in my head but can't quite completely wrap my head around, for instance, the different types of algebraic structures like functors, monoids, monads, etc. How exactly are these different? How can they be used in a programming setting? How are type classes different from regular classes? Can anyone at least point me in the direction of a good book on abstract algebra and functional programming? Someone recommended I learn Haskell but do I really need to learn Haskell in order to understand functional programming?

danmaze
  • 319
  • 3
  • 8
  • 1
    Where did you see the term ‘algebraic structure’? I haven’t encountered that term before. – bradrn Aug 30 '20 at 08:47
  • Oh, I saw it on a blog: https://jrsinclair.com/articles/2019/algebraic-structures-what-i-wish-someone-had-explained-about-functional-programming/ – danmaze Aug 30 '20 at 10:15
  • 1
    Apparently, the author stresses that algebraic structures, type classes, algebraic data types, and abstract data types are all different terms, sometimes erroneously used interchangeably. – danmaze Aug 30 '20 at 10:22
  • 2
    Thank you @typicaldanny! So it seems that the author uses ‘algebraic structures’ to refer to the concepts of functors, monads etc., whereas ‘type classes’ are the language feature used to implement algebraic structures in Haskell. I quite like that distinction actually, but I wouldn’t say it’s a well-known one in the Haskell community. – bradrn Aug 30 '20 at 12:14
  • An algebraic structure is not an algebraic *data* structure (a term which I've never heard). – chepner Aug 30 '20 at 12:58
  • 3
    I think it's probably also worth mentioning: this is a great and interesting field to dive into, but also don't feel like you are *duty-bound* to dive into it right now. You can make a lot of progress in learning and using Haskell without knowing about the depths that mathematicians have reached in their study of abstract algebra. Most of the stuff that actually matters for programming you can pick up along the way -- and if later it seems like a careful study would solidify things for you, it's easy to come back to it another time. – Daniel Wagner Aug 30 '20 at 14:29
  • @chepner Interesting — I’ve heard that term a lot. (Or at least its close relative, ‘algebraic data type’.) – bradrn Aug 30 '20 at 14:45
  • 2
    @bradrn I've certainly heard "algebraic data type", but a data type is not (necessarily) a data structure, and I've never heard "algebraic" applied to the latter. (Though I don't usually think of a linked list as a data type, only a data structure that could implement some abstract data type like a stack.) The article the OP refers to certainly never uses the phrase "algebraic data structure", only "algebraic structure" to describe certain mathematically objects. – chepner Aug 30 '20 at 14:50
  • 1
    @chepner My bad! I meant to type algebraic structures. It's easy to mix up these terms. – danmaze Aug 30 '20 at 14:55
  • @DanielWagner Thanks for the encouragement. I have indeed been feeling a bit _duty-bound_. I think it's mostly because I hear a lot about how much understanding the functional programming paradigm can improve a developer's ability to write code that's easy to test. And I'd like to skill up in that regard. But, on second thought, I'll take your advice. – danmaze Aug 30 '20 at 15:06
  • 1
    @bradrn I think you have provided some clarification on the distinction between "algebraic structures" and "type classes" with your comment. So, essentially, algebraic structures are an abstract structure with a set of finitary operations while type classes refer to a language implementation of these types of structures. – danmaze Aug 30 '20 at 15:19
  • @typicaldanny Yep, that’s my understanding. – bradrn Aug 30 '20 at 23:05

2 Answers2

11

"algebraic structure" is a concept that goes well beyond programming, it belongs to mathematics.

Imagine the unfathomably deep sea of all possible mathematical objects. Numbers of every stripe (the naturals, the reals, p-adic numbers...) are there, but also things like sequences of letters, graphs, trees, symmetries of geometrical figures, and all well-defined transformations and mappings between them. And much else.

We can try to "throw a net" into this sea and retain only some of those entities, by specifying conditions. Like "collections of things, for which there is an operation that combines two of those things into a third thing of the same type, and for which the operation is associative". We can give those conditions their own name, like, say, "semigroup". (Because we are talking about highly abstract stuff, choosing a descriptive name is difficult.)

That leaves out many inhabitants of the mathematical "sea", but the description still fits a lot of them! Many collections of things are semigroups. The natural numbers with the multiplication operation for example, but also non-empty lists of letters with concatenation, or the symmetries of a square with composition.

You can expand your description with extra conditions. Like "a semigroup, and there's also an element such that combining it with any other element gives the other element, unchanged". That restricts the number of mathematical entities that fit the description, because you are demanding more of them. Some valid semigroups will lack that "neutral element". But a lot of mathematical entities will still satisfy the expanded description. If you aren't careful, you can declare conditions so restrictive that no possible mathematical entity can actually fit them! At other times, you can be so precise that only one entity fits them.

Working purely with these descriptions of mathematical entities, using only the general properties we require of them, we can obtain unexpected results about them, non-obvious at first sight, results that will apply to all entities which fit the description. Think of these discoveries as the mathematical equivalent of "code reuse". For example, if we know that some collection of things is a semigroup, then we can calculate exponentials using binary exponentiation instead of tediously combining a thing with itself n times. But that only works because of the associative property of the semigroup operation.

danidiaz
  • 26,936
  • 4
  • 45
  • 95
  • Thanks for an engaging response. If I understand correctly, "algebraic structures" are simply abstract mathematical objects having some specified properties. And purely functional programming languages borrow these constructs to provide features that are better suited to formal mathematical verification. – danmaze Aug 30 '20 at 16:10
  • 3
    @typicaldanny In the case of Haskell at least, I don't think the primary aim is mathematical verification. It's just that if you program against a general "interface" (in Haskell, a typeclass) you can reuse the same code across many different types. Representing algebraic structures like `Monoid` http://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Monoid.html is one application (not the only one) of typeclasses. The methods of the typeclass correspond to the structure's operations, and all instances of the typeclass must respect the laws/properties of the structure. – danidiaz Aug 30 '20 at 16:35
  • a very nice Group Theory interactive site https://nathancarter.github.io/group-explorer/ – Scott Stensland Oct 25 '20 at 12:03
7

You’ve asked quite a few questions here, but I can try to answer them as best I can:

… different types of algebraic structures like functors, monoids, monads, etc. How exactly are these different? How can they be used in a programming setting?

This is a very common question when learning Haskell. I won’t write yet another answer here — and a complete answer is fairly long anyway — but a simple Google search gives some very good answers: e.g. I can recommend 1 2 3

How are type classes different from regular classes?

(By ‘regular classes’ I assume you mean classes as found in OOP.)

This is another common question. Basically, the two have almost nothing in common except the name. A class in OOP is a combination of fields and methods. Classes are used by creating instances of that class; each instance can store data in its fields, and manipulate that data using its methods.

By contrast, a type class is simply a collection of functions (often also called methods, though there’s pretty much no connection). You can declare an instance of a type class for a data type (again, no connection) by redefining each method of the class for that type, after which you may use the methods with that type. For instance, the Eq class looks like this:

class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool

And you can define an instance of that class for, say, Bool, by implementing each function:

instance Eq Bool where
    True == True   = True
    False == False = True
    _ == _         = False

    p /= q = not (p == q)

Can anyone at least point me in the direction of a good book on abstract algebra and functional programming?

I must admit that I can’t help with this (and it’s off-topic for Stack Overflow anyway).

Someone recommended I learn Haskell but do I really need to learn Haskell in order to understand functional programming?

No, you don’t — you can learn functional programming from any functional language, including Lisp (particularly Scheme dialects), OCaml, F#, Elm, Scala etc. Haskell happens to be a particularly ‘pure’ functional programming language, and I would recommend it as well, but if you just want to learn and understand functional programming then any one of those will do.

bradrn
  • 8,337
  • 2
  • 22
  • 51
  • 1
    Thanks for your answer. I was referring to classes as defined in OOP when I mentioned "regular" classes, which you assumed anyway. I guess typeclasses are like interfaces and abstract classes in some sense. Thanks for the links too. – danmaze Aug 30 '20 at 15:53
  • 1
    @typicaldanny You’re welcome for the links! Typeclasses are indeed very much like interfaces — the two language features are very similar and are used for very similar purposes (although there do exist some minor differences between them). Abstract classes are also pretty similar, though I must confess that it’s been so long since I’ve used OOP that I don’t really recall what ‘abstract classes’ are! – bradrn Aug 31 '20 at 07:41