Live data from Hacker News

List is a monad

alexyorke.github.io

31–40 of 187 posts

Re: List is a monad

#31
I think this adds more confusion than it removes.

A list is not a monad. A list is a data structure; a monad is more like a "trait" or "interface." So you can define a List type that "implements" the monad interface, but this is not an inherent property of lists themselves. That's the sense in which a list "is a" monad: the OOP sense.

Haskell's List monad provides a model for nondeterminism. But that certainly isn't the only way List could satisfy the monad interface! It was a deliberate choice -- a good choice, possibly the best choice, but a choice nonetheless.

Re: List is a monad

#32
post #22

Earlier quoted context omitted.

As I so often do, I find it helpful to analogize Monad to Iterator for questions like these, because it's a typeclass/interface/etc. that people are more used to and does not have that aura of "if I feel like I understand it I must not understand it" attached to it that blocks so much learning. You extremely often use iterators in a context where there's no way you could usefully slot in just "any" iterator and have…

This is a cool example but I think it is missing the perspective of what the interface can abstract. For example if I program a data structure to provide an Iterator I get to use these itertool functions for free no matter how complex the data structure is underneath. The trouble I have with Monads is that what get for free doesn't seem very exciting. Feels like I'm stuck in the world of a particular monad like State…

Actually, it sounds to me like you largely have it.

"The trouble I have with Monads is that what get for free doesn't seem very exciting."

I think there's a lot of truth to that, actually.

One of the persistent myths about "monad" is that they somehow "add" to a datatype, that the datatype was able to X and Y, but now that it's a monad now it can do X and Y and Z and M and N. But that's not true. Monad is an interface that can be implemented on things. Once you implement it, you get a lot of little tools, but individually, none of them are necessarily mindblowing, and pretty much by definition it can't be anything the data type couldn't already do.

(Likewise, I'd suggest that what you get with iterator isn't really all that "exciting" either. Useful, oh yes beyond a shadow of a doubt. But it's not exciting. Iterator qua iterator doesn't let you do anything you couldn't do without it.)

The convenience comes in that they're now the same across all monads. mapM does what it does and you no longer need to consult the specific type you are currently using for what it does, and so on for each thing.

If one "removed" monad from Haskell, that is actually what would happen. It's not the Haskell wouldn't be able to do any fewer things. It's just that you'd have to consult each data type for these functions, and they'd be named different things. (And you wouldn't be able to abstract over these operations in different datatypes without basically rebuilding monad in the process.)

I think the standard for "knowing" monad isn't that you can type a bit of a do block and get it to do something, or that you can understand what a particular block of code using list as a monad does; it's when you completely naturally are programming along in Haskell, and you realize "Hey, I've typed

    do
        x 
out, I bet there must be something to do that in Control.Monad" and you go and look it up and find out that yes there indeed is, and add >=> to your bag of tricks.

Re: List is a monad

#33

I think this adds more confusion than it removes. A list is not a monad. A list is a data structure; a monad is more like a "trait" or "interface." So you can define a List type that "implements" the monad interface, but this is not an inherent property of lists themselves. That's the sense in which a list "is a" monad: the OOP sense. Haskell's List monad provides a model for nondeterminism. But that certainly isn't…

Can you explain the nondeterminism part of your comment more?

Re: List is a monad

#34

I think the most intuitive description for a monad I've ever seen is 'flatMappable'. Context: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Usually articles that describe them in a very Math-y way go above my head. But the definition above was immediately clear (I saw it on HN). I think this article is a bit more approachable than others I've read, but it still gets very confusing near the end.

Could you elaborate on that? What does 'flatMappable' mean in this context?

This is a good explanation:

https://users.scala-lang.org/t/what-is-a-monad-in-scala/4169

It's like... what would you call all types that have a .write() method? Writable right? What would you call all types that have a .dispose() method? Disposable. What would you call all types that have a .flatMap() method? Monad obviously.

Re: List is a monad

#35

I think this adds more confusion than it removes. A list is not a monad. A list is a data structure; a monad is more like a "trait" or "interface." So you can define a List type that "implements" the monad interface, but this is not an inherent property of lists themselves. That's the sense in which a list "is a" monad: the OOP sense. Haskell's List monad provides a model for nondeterminism. But that certainly isn't…

Isn’t it the case that for a given functor (on Set) there can only be at most one Monad structure?

Re: List is a monad

#37

I think this adds more confusion than it removes. A list is not a monad. A list is a data structure; a monad is more like a "trait" or "interface." So you can define a List type that "implements" the monad interface, but this is not an inherent property of lists themselves. That's the sense in which a list "is a" monad: the OOP sense. Haskell's List monad provides a model for nondeterminism. But that certainly isn't…

Can you explain the nondeterminism part of your comment more?

Determinism, in that given some set of inputs you only ever receive one output.

Non-determinism, in that given some set of inputs it's possible to receive a collection (a list) of possible outputs.

With lists you can express things like all possible pairings of all possible outcomes, or the Cartesian product:

    ghci> liftM2 (,) ['a', 'b', 'c'] [1,2,3]
    [('a',1),('a',2),('a',3),('b',1),('b',2),('b',3),('c',1),('c',2),('c',3)]
... or in more explicit monadic do-notation:

    ghci> :{
    ghci| do
    ghci|   x 
and so on.

Re: List is a monad

#38

Earlier quoted context omitted.

If all monad instances work differently what is the value of the Monad interface? What kind of usefull generic code can one write against the Monad interface. Related: https://buttondown.com/j2kun/archive/weak-and-strong-algebra...

Lots of useful generic code. MapM is a version of `map` that works with any Monad, `sequence` works with any monad, and so on. These are used very frequently. But the bigger benefit is when syntax sugar like `do` notation comes in. Because it works for any Monad, people can write their own Monads and take advantage of the syntax sugar. That leads to an explosion of creativity unavailable to languages who "lock down"…

What can a Haskell monad do that a Python class cannot? 99% of all monads I've seen only facilitate local state manipulation.

Re: List is a monad

#39
I like to think of a monad as a design pattern for constructing new objects where you pass in a sequence of callback functions, one at a time. A monad’s ‘bind’ operation adds another callback function to the end of a sequence.

The monad interface only requires ways to construct object using callbacks. The ‘bind’ operation takes a callback as an argument, but says nothing about when it’s actually called; it could be immediately, deferred, multiple times, or even never. It’s up to the implementation of the monad, as well as the language, if it’s a lazy language.

This is basically a framework. Like with other frameworks, the principle is “don’t call us; we’ll call you.” Arbitrary computation can happen between callbacks. The framework can do whatever control flow it wants, and this is what often makes frameworks opaque. Hiding control flow is what frameworks do, for better or worse.

So far, none of this is specific to a Monad. The Monad part comes from the type signature of the callback function passed in to flatmap(), which allows ‘bind’ operations to be nested.

Once you know what kind of thing you’re dealing with (frameworks) then you can go into why some frameworks qualify as a monad.

Re: List is a monad

#40
post #5

As far as monad tutorials go, this one seems quite good. I like the categorization of monads between "containers" and "recipes". However, I personally think that monad tutorials tend to give people the wrong impression and leave them more confused than they were before, because they focus on the wrong thing. A monad is not a complex concept, at all. IMO a more useful way to present the topic would be with one separat…

If all monad instances work differently what is the value of the Monad interface? What kind of usefull generic code can one write against the Monad interface. Related: https://buttondown.com/j2kun/archive/weak-and-strong-algebra...

The more constrained your theory is, the fewer models you have of it and also the more structure you can exploit.

Monads, I think, offer enough structure in that we can exploit things like monad composition (as fraught as it is), monadic do/for syntax, and abstracting out "traversals" (over data structures most concretely, but also other sorts of traversals) with monadic accumulators.

There's at least one other practical advantage as well, that of "chunking".

A chess master is more capable of quickly memorizing realistic board states than an amateur (and equally good at memorizing randomized board states). When we have a grasp of relevant, powerful structures underlying our world, we can "chunk" along them to reason more quickly. People familiar with monads often can hand-wave a set of unknowns in a problem by recognizing it to be a monad-shaped problem that can be independently solved later.

Post reply on HN