Hacker News new | past | comments | ask | show | jobs | submit login

A monoid is something that allows you to take two of the same kind of thing and smash them together to be one of that same kind of thing. It also requires you to have an "empty" thing that can be smashed together with any other thing without changing the result.

In code:

    smash :: Monoid a => a -> a -> a
    empty :: Monoid a => a
A monoid is a property of things, not languages, so the idea of "a language without a monoid" doesn't really make sense.



So it sounds like a monoid is a:

Function of arity-2 (possibly expressed as an infix operator)

Which is closed over the set of values that are its arguments/parameters

For a domain (set of input values) which contains a value that converts the function into an identity function when used.

E.g. -

Addition over real numbers (or integers...), becomes an identity function when one arg is 0

Multiplication over real numbers (or integers...), becomes an identity function when one arg is 1

Something along that line?

I guess that makes it useful for a fold/reduce type function where the final result is the same type as the input stream, and the initial value can be identified as a known default.


Exactly right, but for omitting associativity (which, as noted elsewhere, mightybyte skipped).


Yep, it sounds like you pretty much have it. In addition to the two examples you mention, here are some other examples of monoids:

Lists under concatenation Booleans under AND Booleans under OR Numbers under max Numbers under min


Ah, so this is a monoid:

    instance Monoid Int where
        smash 25 x = x
        smash x 25 = x
        smash x y = 2*x^2 - 3*x*y
        empty = 25
Thanks for explaining!


There are also the monoid "laws" (not checked in Haskell):

    empty `smash` x = x -- left identity
    x `smash` empty = x -- right identity
    (x `smash` y) `smash` z = x `smash` (y `smash` z) -- associativity
Your definition doesn't fit any of these. (Edit: you've rewritten to meet the first two; but it is not associative.)


mightybyte didn't state the associativity law in his original definition. As for the left and right identity laws, he did state them, and I did intend my instance to satisfy them (otherwise I wouldn't have special-cased 25, of course), but I messed up. I've fixed my post since.


Just for reference, the laws are stated in full in haskell's docs, https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-....


I was deliberately “acting stupid” to criticize an insufficiently precise definition.

---

> That is usually a terrible idea.

Not at all. Think about the structure of a proof of negation. You make a “silly” assumption and “play along” until you reach a contradiction.


That is usually a terrible idea.


Proofs by contradiction do not require you to play dumb, you can just present them as they are.


I left out associativity because I was focusing on the ELI5 part.


They are not checked in Haskell, but they are definitely relied on by existing code.


For anyone who was wondering, catnaroek was being sarcastic.


I think combining 25 and x should yield x.


Oops, yes, my bad.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: