Live data from Hacker News

Monads are monoids in the category of endofunctors

sambernheim.com

231–240 of 241 posts

Re: Monads are monoids in the category of endofunctors

#231
post #24

This post is very wrong. Being a monoid in the category of endofunctors means something very different from being a monoid in the normal sense (they're related in a category-theoretic way, but the similarity is at a very abstract level). Simple sequences have a lot of structure which mean they are a lot of different things; it is true that sequences are all of monads, functors, and monoids, but the latter structure i…

> means something very different from being a monoid in the normal sense Yet you didn't say how exactly different. I understand I probably need to know category theory for that, yet nevertheless OP's post was useful, fulfilled some curiosity, but your comment didn't, besides leaving feeling "it's complex", sorry. I'd really appreciate if someone one day wrote as clear explanation of monads as OP's, but at the same ti…

I can't explain the "a monad is just a monoid in the category of endofunctors" thing simply; I barely understand it myself, and I'm actually sceptical that it's even true at all. I certainly don't think it's a useful way of learning anything.

If you're asking about monads in general, I think trying to understand the generic concept before understanding a bunch of concrete examples is the problem. https://m50d.github.io/2013/01/16/generic-contexts was my effort at explaining applicative functors (which are not quite monads, but monads are a fairly small extension of them) "from the bottom up", starting with some useful concrete things that happen to be applicative functors, and discovering that abstraction.

Re: Monads are monoids in the category of endofunctors

#232
post #166
post #154

Earlier quoted context omitted.

> No, this is just not true, are we using the same JavaScript? JavaScript's functions change only based on modified application state, not on any other side effect. If you read some file (or remote URL) multiple times, you may get different data each time. Haskell makes "functions" with this property clearly distinct from regular functions. Most languages, including JavaScript, don't. That's what matters, not whether…

> If you read some file (or remote URL) multiple times, you may get different data each time. True, but just like in Haskell that data is not returned by the function, JavaScript functions are pure for I/O.

Well, either it's impossible to read a file (or remote URL) in JavaScript, or the data gets into your program somehow. Whether you get it as a plain value, a promise, or a callback is not really relevant; it comes into your program looking like a normal, idiomatic function evaluation (because passing callbacks to normal functions like Array.map is perfectly idiomatic JavaScript). There is no practical way to separate a JavaScript program into fragments that depend on external mutable state (files, remote services) and fragments that don't, because a function that accesses and depends on external mutable state (say, a calculation that uses a lookup table that it loads from a file) looks the same, at API level, as one that doesn't.

Re: Monads are monoids in the category of endofunctors

#233
post #163

Earlier quoted context omitted.

> I'm just saying if you did care to, you very well could find a pretty meaningful and useful definition for "state". I'm not at all convinced. The thing that actually determines the performance of real-word programs these days (after algorithm choice) is cache efficiency, and no mainstream programming model gives you a "state" model that actually lets you reason about that. > Look at it this way: the only reason you…

> The thing that actually determines the performance of real-word programs these days (after algorithm choice) is cache efficiency > Today's programmers put way too much focus on performance So statefulness is a meaningless concept in functional programming because... programmers put too much focus on performance? and cache efficiency is what matters? Is there a logical chain of implications I'm missing here? I feel…

Well, I got lost trying to follow you. My position is: Functional programming more or less means expressing (denotational) computation without using a concept of (hidden, mutable) state. This is a good approach because it makes it easier to write correct programs. I disagree with the argument that a programming language should expose state at the language level (rather than making it a detail of the implementation) for the sake of performance on two levels: performance is less important than correctness, so it's a bad idea to sacrifice correctness for performance in language design, but also exposed state doesn't even help you improve performance (because cache efficiency is what matters).

Re: Monads are monoids in the category of endofunctors

#234
post #232
post #166

Earlier quoted context omitted.

> If you read some file (or remote URL) multiple times, you may get different data each time. True, but just like in Haskell that data is not returned by the function, JavaScript functions are pure for I/O.

Well, either it's impossible to read a file (or remote URL) in JavaScript, or the data gets into your program somehow. Whether you get it as a plain value, a promise, or a callback is not really relevant; it comes into your program looking like a normal, idiomatic function evaluation (because passing callbacks to normal functions like Array.map is perfectly idiomatic JavaScript). There is no practical way to separate…

Well that's true. I do think there's some value to the fact that if you call a JavaScript function you are guaranteed that no I/O has been executed (provided no on is using the old sync API's) before the function returned. I lean on this property often, and I don't know any other language besides Haskell that has this property.

I do agree that Haskell is even stronger because it doesn't just guarantee the I/O has not yet been executed yet, it also reveals the intent of I/O through the use of the I/O monad.

Re: Monads are monoids in the category of endofunctors

#235
post #217

Earlier quoted context omitted.

> means something very different from being a monoid in the normal sense Yet you didn't say how exactly different. I understand I probably need to know category theory for that, yet nevertheless OP's post was useful, fulfilled some curiosity, but your comment didn't, besides leaving feeling "it's complex", sorry. I'd really appreciate if someone one day wrote as clear explanation of monads as OP's, but at the same ti…

Let me give it a shot. Monads as in category theory are a bit more abstract than this explanation, but for the purposes of programming you can think like this: A functor has a `map` mechanism, which takes a value A and a function B, and returns something that has the same type as A. A simplistic example of a "mappable" that isn't a functor is `const map = setTimeout`: it technically take a value A (the time) and a fu…

> A monad, in addition to being a functor, must also not have extra funky semantics. A example of a functor that isn't a monad is `Promise`.

Not quite. You've come up with a great example of a problem with JavaScript Promise, but the problem is actually that it isn't a functor (it violates the composition law, for example).

Re: Monads are monoids in the category of endofunctors

#236
post #235
post #217

Earlier quoted context omitted.

Let me give it a shot. Monads as in category theory are a bit more abstract than this explanation, but for the purposes of programming you can think like this: A functor has a `map` mechanism, which takes a value A and a function B, and returns something that has the same type as A. A simplistic example of a "mappable" that isn't a functor is `const map = setTimeout`: it technically take a value A (the time) and a fu…

> A monad, in addition to being a functor, must also not have extra funky semantics. A example of a functor that isn't a monad is `Promise`. Not quite. You've come up with a great example of a problem with JavaScript Promise, but the problem is actually that it isn't a functor (it violates the composition law, for example).

Hmm, fair point.

I couldn't think of another popular construct in JS that is a proper functor. Do you have any better suggestions?

Re: Monads are monoids in the category of endofunctors

#237

Hands up if you've never actually seen FP out in the wild doing something. Not saying it's not out there or useful - just saying that after 20 years I'm yet to come across it once.

Well... chances are you've made thousands of phone calls through switches running Erlang. You may have used Emacs, Discord, Facebook, Pinterest, Spotify, Font Awesome, xmonad or visited web sites running Elm or an Elixir backend... or even driven a Volvo. Here's a list of companies using Haskell, with similar links to other functional languages: https://github.com/erkmos/haskell-companies . It includes names like Fac…

I meant in a professional capacity. But appreciate the use-case examples.

Re: Monads are monoids in the category of endofunctors

#238
post #236
post #235

Earlier quoted context omitted.

> A monad, in addition to being a functor, must also not have extra funky semantics. A example of a functor that isn't a monad is `Promise`. Not quite. You've come up with a great example of a problem with JavaScript Promise, but the problem is actually that it isn't a functor (it violates the composition law, for example).

Hmm, fair point. I couldn't think of another popular construct in JS that is a proper functor. Do you have any better suggestions?

Any of the standard functor-but-not-monad examples, e.g. multidimensional arrays (where you can implement map but can't implement map2 or flatMap, because the dimensions won't necessarily line up)?

Re: Monads are monoids in the category of endofunctors

#239
post #234
post #232

Earlier quoted context omitted.

Well, either it's impossible to read a file (or remote URL) in JavaScript, or the data gets into your program somehow. Whether you get it as a plain value, a promise, or a callback is not really relevant; it comes into your program looking like a normal, idiomatic function evaluation (because passing callbacks to normal functions like Array.map is perfectly idiomatic JavaScript). There is no practical way to separate…

Well that's true. I do think there's some value to the fact that if you call a JavaScript function you are guaranteed that no I/O has been executed (provided no on is using the old sync API's) before the function returned. I lean on this property often, and I don't know any other language besides Haskell that has this property. I do agree that Haskell is even stronger because it doesn't just guarantee the I/O has not…

> I do think there's some value to the fact that if you call a JavaScript function you are guaranteed that no I/O has been executed (provided no on is using the old sync API's) before the function returned. I lean on this property often, and I don't know any other language besides Haskell that has this property.

Are you just talking about the absence of shared-memory threading (which you also get in, say, OCaml, or even Erlang or idiomatic Python)? I can understand the value of not having to reason about arbitrarily interleaved executions, but not how that particular kind of sequencing of I/O specifically is more useful than that.

Re: Monads are monoids in the category of endofunctors

#240

Earlier quoted context omitted.

A monad is a triple: 1. A type constructor M of a single argument 2. A function of type a -> M a 3. A function of type M (M a) -> M a subject to the monad laws. So the 'array monad' is the triple (Array, \x -> [x], Array.concat) and the 'option monad' is the triple (Option, \x -> Some(x), \x -> match x | Some(o) => o; None => None). Saying a type 'is' a monad is imprecise but just means it has an associated monad ins…

Wow that's clearer. I wonder if just a list of examples (and counter-examples) would be enough to explain monads (preferrably with configurable syntax for Haskell-deprived folks). Btw, I think you got a mistake there, in the third part of Option should be "Some(Some(o)) => Some(o), Some(None) => None, None => None", otherwise o can be not an Option at all.

Your first two cases are equivalent to the `Some(o) => o` case; the syntax I used was a bit ad-hoc but the following F# typechecks:

    let join_option oo =
        match oo with
        | Some(o) -> o
        | None -> None
Post reply on HN