4 ms·
Monoids without tears (2014)
- ZenoArrow 12y agoThis is the first 'F# For Fun and Profit' article I've read, I was very impressed with how the author (Scott Wlaschin?) breaks the subject of monoids down so clearly, something tells me that the author will be helping me out a lot in the coming months.
- agumonkey 12y agoI found Wlaschin work well balanced between accessible and complex. https://vimeo.com/97344498Vimeo https://vimeo.com/97344498Vimeo https://speakerdeck.com/swlaschin https://speakerdeck.com/swlaschin http://www.slideshare.net/ScottWlaschin http://www.slideshare.net/ScottWlaschin And wip book https://leanpub.com/understandingfunctionalprogramming https://leanpub.com/understandingfunctionalprogramming
- gavinpc 12y agoMonoid != Monad There seems to be some confusion about which one is confusing. The hardest part of understanding monoids is accepting that yes, that's all there is to it. The fuss is about the other one.
- ZenoArrow 12y agoYes, I know that a monoid and a monad are two different terms, there's no confusion. However, despite monoids being relatively simple, my first introduction to monoids was this... http://gettingsharper.de/2015/03/03/understanding-monoids-using-f/ http://gettingsharper.de/2015/03/03/understanding-monoids-us... ... which I didn't find beginner friendly. YMMV.
- gavinpc 12y agoBut what is the use of understanding monoids, other than as a step towards understanding monads? No criticism... I read all of these submissions. But the ones which only cover monoids [0] leave me wondering, Okay, now what? So I guess the confusion is mine. [0] Other than to say that monads are "very different things".
- ZenoArrow 12y ago> "But what is the use of understanding monoids, other than as a step towards understanding monads?" I'm sorry, but I don't follow. It's just terminology for communicating more efficiently with other programmers (and mathematicians, in this case). They're both a group of ideas with a label. Why would one group only serve to introduce the second group?
- gavinpc 12y agoYou're completely right — I stand corrected. The OP covers practical usages at the end of the piece, as well as in a follow-up piece for that sole purpose. Thanks.
- deleted 12y ago[deleted]
- zak_mc_kracken 12y agoDid you ever realize that there is a similarity between addition (+) and zero (0) and multiplication (x) and 1? Can you guess what it is? If you add something to zero, you get that same thing. If you multiply something by one, you get that same thing. That's what a monoid is: the generalization of the idea that if you can find an operator on a certain set (+ and x) and a special member of that set (0 and 1) that obey a few simple laws, then that thing is a monoid. So we have identified two monoids: (Integer, +, 0) and (Integer, x, 1). Of course, this works with Floats and a few other number-based types. I'll give you another example of a monoid: (String, append, ""), because if you add the empty string to a string, you get that same string back. Now monads are a different topic. They are a monoid but understanding them requires a little bit more background, so I'll stop there.
- jfarmer 12y agoOther "every day" monoids: - (Array, concat, []) - (Floating point numbers, min, +Infinity) - (Floating point numbers, max, -Infinity) - (Boolean, AND, true) - (Boolean, OR, false) - (Subsets of set S, union, {}) - (Subsets of set S, intersection, S) - (Functions of type S → S, composition, the identity function) You'll often see folks writing functions from Strings to Strings but returning _null_ or the like in the "empty" case instead of an empty String. Having them instead return the "identity" element of the relevant monoid will always result in a simpler, more composable interface.
- rahimnathwani 12y ago> Having them instead return the "identity" element of the relevant monoid will always result in a simpler, more composable interface. But there may be more than one relevant monoid, and thereby more than one identity element. In the case of a function which returns an integer, should I return the multiplicative identity, or the additive one?
- jfarmer 12y agoFor a given problem, there's often some natural monoidal structure underneath the hood even if the operations aren't explicitly part of the type signature. For example, it's "natural" for the sum of an empty list to be 0 but the product of an empty list to be 1. Why? So that the "hidden homomorphism" is preserved (here ++ is list concatenation): sum(listA ++ listB) == sum(listA) + list(listB) product(listA ++ listB) == product(listA) * product(listB) For similar reasons, given some predicate P is some predicate, the any? should return false for an empty list and all? should return true so that the following hold: all?(P, listA ++ listB) == all?(P, listA) && all?(P, listB) any?(P, listA ++ listB) == any?(P, listA) || any?(P, listB) Behind it all we're not only transforming values of TypeA into values of TypeB , we're doing it in a way that respects some underlying monoidal structure. If you want to think of it in a more programmer-centric way, any time you have an operation that could be as a fold[1] there is an underlying monoidal structure. Monoids permit folding, folding implies the existence of some monoid. [1]: http://en.wikipedia.org/wiki/Fold_(higher-order_function) http://en.wikipedia.org/wiki/Fold_(higher-order_function)