News for hackers. Stuff that matters.
Re:Monad Confusion and the Blurry Line Between Data and Comp... by yccs27 on Saturday August 06, 2022 @07:49AM (#32367257)
That's pretty typical for understanding mathematical concepts. You start knowing the definition (interface), but with absolutely no intuition for it, so it seems mysterious. Then you work though some examples, theorems, use-cases etc. to build understanding, and the concept seems to become more than the sum of its parts. At some point, you look back at the definition with your new intuition and realize: There really isn't anything more to it than this definition! Everything else just follows from that!
Re:Monad Confusion and the Blurry Line Between Data and Comp... by spion on Saturday August 06, 2022 @09:10AM (#32367770)
I do know what concepts map to it, I understand all common monads (including IO) as well as monad transformers. I think ZIO style monads (combined reader, error and effect monad) are pretty awesome for building backend apps, especially the reader bit which solves the common "contextual data" problem typically solved by threadlocalstorage or CLS or OOP in other languages

I still find "monad" as a concept underwhelming and meaningless. I can put `flatMap` and `wrap` on a lot of things but that won't make them interesting or useful. The individual use cases are interesting, the concept isn't - seems like an unnecessary overgeneralization.

Re:Monad Confusion and the Blurry Line Between Data and Comp... by kmill on Saturday August 06, 2022 @11:35AM (#32368999)
I agree with you that there's no inherent magic to the monad concept, but there really is something neat about the monad generalization -- it's not just a senseless abstraction. That meme "a monad is just a monoid in the category of endofunctors" has merit here. If you already believe that monoids are a useful enough concept, and also if you believe functors are useful enough, then this is a basic structure that pops out. It's a higher-order one, which makes it that much harder to grasp, which only amplifies any possible disappointment :-)

One place this generalization is useful is in defining other structures, for example traversable functors, which as part of their definition need to commute with every other monad. Sure, you won't be using most monads, but it's easier to define a traversable functor that works for all monads instead of the small subset of computationally useful ones.

The deep part to monads is that they (well, a large class of them, the "finitary" ones) end up classifying Lawvere theories. This means that each monad is secretly encoding some suite of composition laws for operators of arbitrary arity. I'll just give an example with the list monad. If you have a list [1,2,4,2], then you can think of it as being a function, where `map` takes each integer (a "variable") and substitutes it for some value, yielding a list -- so in this way the list is an operator with an input per int. The monad part is that you can compose it with other operators by using `flatMap`. For example, if 1 -> [1], 2 -> [2, 3], and 4 -> [2], then the `flatMap` gives a new "function" [1,2,3,2,2,3] from integers to lists by splicing in other operators (and `wrap` is a way to tell `flatMap` that you want to preserve a particular variable, so to speak). I think this is a way to think about why monads have anything to do with computation -- a value of `m a` where `m` is a monad is a computation with "`a`-shaped holes," and `flatMap` is a way to plug other computations into these holes.

Anyway, that's a lot to say for this, but I'd come across Lawvere theories earlier this year and it gave me a new appreciation for monads after years of just using them while programming. (Disclosure: I'm also a pure mathematician, so I understand if others won't share this appreciation.)

Re:Monad Confusion and the Blurry Line Between Data and Comp... by yccs27 on Saturday August 06, 2022 @03:13PM (#32370748)
To expand on the “classifying Lawvere theories“ part, the relevant concept here is algebras over a monad. An algebra a over m is determined by a function merge :: m a -> a which “plays nice“ with the monad structure [0].

For example, integers with the sum function form an algebra over the list monad, because

1) for any list of ints, the sum is an int

2) the sum of [n] is just n

3) summing recursively is the same as summing over the flattened list.

More generally, the algebras over the List monad are exactly the monoids, with ‘merge [a, b]‘ as the monoid operation. Algebras over the Maybe monad are pointed sets, with ‘merge Nothing‘ as the distinguished point. A lot of algebraic structures (Lawvere theories) can be defined by a monad this way.

[0] Laws that ‘merge‘ should satisfy: merge (return x) == x fmap merge (merge mx) == merge (join mx)

Re:Monad Confusion and the Blurry Line Between Data and Comp... by spion on Saturday August 06, 2022 @03:48PM (#32370986)
I don't understand how this is related to monads - there is nothing in the general monad interface that even allows you to go `m a -> a`, so something being a monad doesn't seem sufficient to be able to define that algebra.

Seems to me that the entire interesting bit is "provided" by `a` being a monoid. (I agree that monoids are really interesting)

Re:Monad Confusion and the Blurry Line Between Data and Comp... by kmill on Saturday August 06, 2022 @06:52PM (#32372312)
Here's another way to say the general idea, by way of example. Secretly, list is "the" exemplary universal monoid. Given any `a`, then `list a` gives you the free monoid generated by `a`, with composition given by `++` and the identity given by `[]`. Now, let's say you have some `a` such that you're able to come up with a function `ev : list a -> a` that's a monad algebra (i.e., it satisfies the two axioms given by yccs27). Then you're able to conclude that `a` is a monoid(!) and you can extract the monoid structure in the following way: `\ (x y : a) -> ev [x, y]` is the binary operation and `ev []` is the unit. (In particular, `ev` must be some `list.fold`.)

I called it `ev` because it's an evaluator/interpreter. To be able to write such a `m a -> a` function, `a` needs to have the same kind of structure that `m` is somehow representing, and you need to be able to map the operation that `m` "contains" to corresponding operations for `a`.

This is that business about free monads being useful for organizing how you write interpreters I believe.

Re:Monad Confusion and the Blurry Line Between Data and Comp... by spion on Sunday August 07, 2022 @05:54AM (#32375224)
> Then you're able to conclude that `a` is a monoid

Yep, which is why I'm saying all the interesting bits come from `a` being the monoid in that example.

In the free monad interpreter example, I have no idea though.

Re:Monad Confusion and the Blurry Line Between Data and Comp... by kmill on Sunday August 07, 2022 @11:38AM (#32377281)
If there's a point to any of this, I think it's monads let you package up some algebraic structure in the form of a function `m a -> a` that satisfies certain properties, and then you can pass such a function around without any reference to the fact that `a` implements that algebraic structure. This function is the interface. (Is there real practical significance? I'm not sure, but I'm not trying to argue that :-) )

> all the interesting bits come from `a` being the monoid in that example.

Yeah, there's nothing deep there. I just said what I said to underscore that the converse is true, that if anyone were to hand you such a `list a -> a` function then it's encoding some monoid structure on `a` (one of often very many).

Re:Monad Confusion and the Blurry Line Between Data and Comp... by hither_shores on Saturday August 06, 2022 @04:31PM (#32371350)
> there is nothing in the general monad interface that even allows you to go `m a -> a`, so something being a monad doesn't seem sufficient to be able to define that algebra.

You've got the direction backwards: the point is to characterize all `m`-algebras, not to construct particular ones.

This is closely related to the usual duality between types and values. It's very common for people new to TypeScript, for instance, to think that `{a: string} | {b: number}` should be `{a: string, b: number}`, because they're thinking primarily in terms of records as sets of fields, not types as sets of values. But making the type bigger makes the set of things you can say about its values (i.e. the space of functions out of it) smaller. Algebras are similarly the "value-like" counterparts to "space-like" monads.

Re:Monad Confusion and the Blurry Line Between Data and Comp... by spion on Sunday August 07, 2022 @08:57AM (#32376125)
I have no idea what you mean.
Re:Monad Confusion and the Blurry Line Between Data and Comp... by yccs27 on Sunday August 07, 2022 @06:52AM (#32375481)
The important point is that each monad (e.g. list) corresponds to an algebraic structure (like monoid). To study the set of algebraic structures, you can also study monads
Re:Monad Confusion and the Blurry Line Between Data and Comp... by AzzieElbab on Saturday August 06, 2022 @09:43AM (#32368007)
It is a pretty good concept to scare away non-monadic ppl. Cool word too
Re:Monad Confusion and the Blurry Line Between Data and Comp... by plaguepilled on Saturday August 06, 2022 @09:23AM (#32367859)
This is an underrated observation IMO. Mathematics gets mystified so often when it really is just a very useful (and aesthetically appealing) method to approach problems. There's no secret sauce.