Hacker News new | ask | show | jobs
by hawkice 2112 days ago
In my experience, Monad, Applicable, and Monoid are probably the only ones I'd use in Haskell, and maybe none of them in languages without good inference and general support.

Pretty wild ideas, though. Fair chance they'd be more confusing than using more specifically named instances, but solid ideas where the class instance documents that you're using the pattern, instead of describing the preferred interface.

4 comments

You've definitely used Functors or Semigroups as well, you just didn't realize it.
Here is my problem with these ideas in programming: if you recognize that some common construct is in fact a semigroup or functor, does knowing this actually buy you anything?

I suppose it might help sometimes when designing an abstraction, to guide you to some nice properties, such as easy composition.

While playing around with a problem at work involving Markov chains and graph connectivity, I found it useful to know that I could write (in Java) a generic method that performed "exponentiation by squaring" on semigroups.

So, in addition to being able to raise numbers to powers I could also use it on matrices whose elements belonged to a semiring.

That is, I could use the same code on a matrix of doubles with "times" and "plus" (for the Markov chains), as well as a matrix of booleans with "and" and "or" (for the graph connectivity).

(Of course, I could have used special purpose libraries, but these were small problems and it was fun. :)

> if you recognize that some common construct is in fact a semigroup or functor, does knowing this actually buy you anything?

At least in Haskell one thing it means is you can use lots of new helper functions.

> guide you to some nice properties, such as easy composition.

Yep, which gets you code re-use for one.

I think it isn’t often said that one reason a lot of these classes work in haskell is the lazy evaluation (or arguably the pure functions allowing the compiler to inline things and skip evaluation).

You can write monoid and foldable interfaces in java but in haskell finding the head of a list with a monoid and foldmap is constant time (and the first or last element of a tree is logarithmic) but a java implementation would be linear.

There is sort of a "jump" from those to the ones less oriented around (->) but truer to the math, but I can assured I have in fact used https://hackage.haskell.org/package/categories (a prime example of the latter sort) in production and it was genuinely useful.
I wish semilattices got more play. They're so ubiquitous when talking about distributed systems. I remember a keynote on eventual consistency in databases that could have been replaced with "make your merge operation the join of a semilattice."
Any resources for semilattices that you do like? I'm also finding them mentioned around CRDT & distributed systems threads.
My all-time favorite is the original LVars paper: https://users.soe.ucsc.edu/~lkuper/papers/lvars-fhpc13.pdf
> Conclusion ... monotonicity serves as the foundation of deterministic parallelism

That's what the recent CALM Theorem [1] paper uses as the first theorem:

> Monotonicity is the key property underlying the need for coordination to establish consistency, as captured in the CALM Theorem:

> THEOREM 1. Consistency As Logical Monotonicity (CALM). A problem has a consistent, coordination-free distributed implementation if and only if it is monotonic.

Unsurprisingly, this paper is reference 32 in CALM. Maybe I should check out some other papers referenced here... Thanks for the recommendation!

[1]: https://cacm.acm.org/magazines/2020/9/246941-keeping-calm/fu...

I read Birkhoff's "Lattice Theory" many years ago, then wandered down some idiosyncratic path, so, no, I'm sorry. I really don't have anything.