Live data from Hacker News

Monads are monoids in the category of endofunctors

sambernheim.com

131–140 of 241 posts

Re: Monads are monoids in the category of endofunctors

#131
post #60
post #50

Earlier quoted context omitted.

> If you cannot communicate with a beginner in language they understand, A.) you don't really understand it either This is true, but the problem is that people will always prefer the explanation that is, as the saying goes, "simple, neat, and wrong" over the explanation that is more complicated, especially if they (and possibly the person explaining) aren't aware that the simplified version is wrong. Even if one star…

You have to start with the 'simplified but not technically perfectly correct' and then add in the nuances to get to the real point. Starting with words like 'functors' that most software engineers today will not be able to define is not useful.

> Starting with words like 'functors' that most software engineers today will not be able to define is not useful.

But the parent post https://news.ycombinator.com/item?id=28476325 to which lmm was responding https://news.ycombinator.com/item?id=28476569 said "Wait, a functor is just a pure unary function?" If someone asks you the definition of a technical term, you sort of have to at least refer to the technical term.

Re: Monads are monoids in the category of endofunctors

#132
post #128

Earlier quoted context omitted.

To add, I suspect that the Haskell type notation is not intuitive to people not familiar with it. For anyone wondering, (a -> b) -> f a -> f b means "A function taking a function from one type to another "(a -> b)" and a functor applied with one type "(f a)" and returns a functor applied with another type "(f b)".

I do think familiarity plays a big role. I find the Haskell syntax much more pleasant than Java, even though I'm perfectly familiar with both. The equivalent signature in Java (if we could abstract over type functions) would be: interface Functor > { Function , F > map(Function f); } You'll find very similar in Scala's `cats`, up to some currying and reordering. [0] [0] https://typelevel.org/cats/typeclasses/functor.…

I absolutely agree, I was just adding the explanation for anyone unfamiliar with the syntax.

Re: Monads are monoids in the category of endofunctors

#133
post #128

Earlier quoted context omitted.

I do think familiarity plays a big role. I find the Haskell syntax much more pleasant than Java, even though I'm perfectly familiar with both. The equivalent signature in Java (if we could abstract over type functions) would be: interface Functor > { Function , F > map(Function f); } You'll find very similar in Scala's `cats`, up to some currying and reordering. [0] [0] https://typelevel.org/cats/typeclasses/functor.…

I absolutely agree, I was just adding the explanation for anyone unfamiliar with the syntax.

And I was building on yours :) I hope you didn't mind.

Re: Monads are monoids in the category of endofunctors

#134

> This phrase is the cheeky line to (somewhat) formally define the monad It's actually a satirical joke[1] that people started taking way too seriously. Honestly, imho people should never use this line when explaining monads. It's like saying 'C is a purely functional programming language!' because Conal Elliott, around the same time, wrote[2] a parodic blog post making fun of purely functional programming zealots. […

Conal Elliott wasn't making fun of pure functional programming zealots. Elliott is a pure functional programming zealot, and was making fun of Haskellers who defend the IO type as a purely functional way to express effects. He thinks the IO type sullies Haskell here, and that we should have picked a different representation for effects (historically, that was true FRP, something he conceived with the late Paul Haduk).

Re: Monads are monoids in the category of endofunctors

#135
post #124
post #118

Earlier quoted context omitted.

> But the interesting part of Haskell's I/O isn't the implementation, it's the (pure) API that it uses, and Javascript has nothing like that. No, I insist JavaScript really has a pure approach to I/O, quite like Haskell. There is literally no side effects except for application state mutation from the perspective of a JavaScript function (if you disregard the few deprecated synchronous API's). And this pure API has p…

> There is literally no side effects except for application state mutation from the perspective of a JavaScript function (if you disregard the few deprecated synchronous API's). That's a pretty big "except" - there are no side effects except for all the side effects (and there's nothing unique about JavaScript there, that much is the same as almost any other language). JavaScript's approach to I/O, like most language…

> That's a pretty big "except" - there are no side effects except for all the side effects (and there's nothing unique about JavaScript there, that much is the same as almost any other language)

It's not like Haskell doesn't have those either though, I don't think it's a very big except. Discussing synchronous I/O in JavaScript is not interesting, were not littering our Haskell with unsafePerformIO either.

> JavaScript's approach to I/O, like most languages, uses things that look like functions but aren't functions, in that they give different outputs for the same inputs.

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.

> The whole point of Haskell's I/O system, the thing that separates it from other languages, is that it doesn't do that; in Haskell your functions are actually functions and I/O operations are very clearly not functions.

Sure, in the current Haskell that's true. In previous iterations of Haskell this wasn't always the case though, monadic I/O wasn't the first pure system, we also had stream based and continuation/callback based I/O, the latter being basically what JavaScript does.

Re: Monads are monoids in the category of endofunctors

#136
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…

Right.

Things could be headed off early where the blog defines a monoid. The definition given is roughly what the average mathematician would call a monoid, but a category theorist would complain saying that it only defines a monoid in the category of sets.

But monads are not monoids in the category of sets. They are monoids in the category of endofunctors! So the blog post is going off the rails from here on.

Re: Monads are monoids in the category of endofunctors

#137
post #64
post #57

Earlier quoted context omitted.

Not every type constructor is a functor.

What makes a type constructor a functor, what's the difference

I might get flack from the FP purist crowd, but I like to think of functors as containers + context.

- 5 is a value. Its type is int

- int is a type

- T is a type parameter. Like the x in "f(x)", we have to pass one in to evaluate it

- List is a type constructor. It takes a type, T, and spits out a new, "compound" type. It will "contain" T's.

- [3,5,7] is a list. Its type is List. We fed the type "int" to List to construct a new type

- List is a functor because it "contains" T's. List "contains" ints.

- F -> () (a function which takes a T and returns nothing) is a type constructor. It's not really a functor. There's ways in which it technically can be (e.g. decorators in python) but for the sake of pedagogy and giving a counterexample, I'm going to say it's not, because you usually aren't going to map over something like that.

- because functors "contain" other values, you can apply a function to the contents, without changing the container context. This is called map. It may change types, eg mapping sqrt over a list of ints could give floats. But it always gives the same "container type"

The tricky bits:

- To be a true blue functor, there has to exist an identity function that is a no-op and gives you the same types and values back. You needn't define it, it just has to be possible to define.

- functors need not actually "contain" anything, nor the contained value be primitive data. But they always have this wrapper-like feel to them, with an outer type, an inner type, some context/data/value/computation, and the ability to map over that inner value. E.g. Optional could contain nothing, but you can still map over it.

- it's not necessary to be able to dereference or "dispense" the contained value. Sometimes, like the IO monad pattern, the inner value gets "stuck". it never leaves the IO, it's only ever (flat)mapped over.

- the inner value can be: nothing, a single datum, a collection of data, a function, a computation, another functor, another type constructor...almost anything you could assign to a variable.

- well-known functors include: List, Dict, Optional, Result, Future, Generator, IO, Tree. T* (pointer to a T). Virtually all container types.

Hope that helps

Re: Monads are monoids in the category of endofunctors

#138
post #123

Earlier quoted context omitted.

I should be clear: you don't have to sell me on Haskell or these other concepts. I would love to add all that stuff to my toolbelt. I'm suggesting that the zoo of new terminology makes the effort barrier to doing so much higher than it needs to be. I'm sure some of it really is warranted, but my experience looking at formal math and logic is that they make things a lot harder than they need to be by introducing terms…

Alright, but you were praising the article for conveying the meaning of the words, when those meanings are useless without some sort of interesting application. I believe people find monads difficult to grok not because the definition is hard to remember, but because the situation in which it is useful to distinguish the type class is abstract and frankly not super useful in most cases. Funny thing about zoos of new…

> those meanings are useless without some sort of interesting application

They're useful when trying to grok other blog posts or discussions that talk about them (often in service to some further concept that you have no hope of understanding without knowing that first layer of terminology)

> My brain had been getting stuck on this random terminology and this just unclogged it

Exactly! What I'm requesting is that the FP community at large gets more comfortable with the idea of providing those "X is roughly just Y" comparisons for newcomers, so they don't get stuck on all the random terminology and can be "unclogged".

Re: Monads are monoids in the category of endofunctors

#139
post #5

Wait, a functor is just a pure unary function? And an endofunctor is just one of those where the argument type and return type are the same? This could have been explained to me years ago, in five minutes? Sometimes it makes me mad that so much confusion (and as another commenter put it, gatekeeping) has been sown in FP circles through the invention of pointlessly-obfuscated terminology for everything (and through -…

Edit 2: I'm sorry for getting a little inflammatory with my original comment. I have a headache today, and one of my biggest frustrations is needlessly poor communication of concepts, especially if it's willful, and especially if it wastes the potential of capable people who could otherwise be given understanding.

With that said I may have gone on a bit of a rant here and made some generalizations, and I don't feel good about that aspect, so I apologize.

Re: Monads are monoids in the category of endofunctors

#140

Earlier quoted context omitted.

Functors are type constructors, not functions (which map values). But you could be forgiven the misunderstanding, because it is easy to trip over this distinction given the identical syntax. So, to make this absolutely clear, a monad is a type constructor in functional programming. This is why I personally prefer the more “creative” explanations of monads, because they attempt to explain what the monad is doing to th…

I don't like creative explanations. Definitions are easier. A functor is a PAIR, please notice the emphasis, of a type constructor F and a map function with the following signature: a -> b -> f a -> f b. Its not a type constructor, it's a pair of two things, the type constructor AND its map function. Now that we said what it is we provide the usual simple example of Array, Record or Option, show the type constructors…

> I wish people understood that fp is much easier to understand by reading definitions.

I wish more FP writers understood that not everyone has the same neurotype, and "easier to understand by reading definitions" is far from a universal statement.

Post reply on HN