Monoids
for
Programmers
(Scala flavor)
Vlad Patryshev, 2013
See common pattern?
You see Monoids!
Monoid Rules
1) a Op b = c
2) Zero Op a = a Op Zero = a
signatures:
Op: (T, T) => T
Zero: () => T // or rather just T
but wait, there's more!
Monoid Rules - associativity
(a Op b) Op c == a Op (b Op c)
Not everything is associative
5-(3-2) != (5-3)-2
avg(10, avg(30, 50)) != avg(avg(10, 30), 50)
Magma - like monoid, but no associativity and no unit
Monoid Rules - associativity
(a1 Op (a2 Op (a3 Op (a4...))))
aka fold
(Zero /: a) (x Op y)
Can regroup and run in parallel: thanks to associativity!
This is what empowers Map/Reduce
Mappings between Monoids
f: A → B
f(ZeroA) = ZeroB
f(x OpA y) = f(x) OpB f(y)
e.g.
Free Monoid
take any function, f: A → B
this is equivalent to specifying...
f': List[A] → B
where
f'(Nil) = ZeroB
f'(list1 + list2) = f'(list1) OpB f'(list2)
List[A] is a Free Monoid on A
any type
a monoid
Free Monoid - example
Suppose we have...
object WeekDay extends Enumeration {� val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value�}
and a function
WeekDay=>Int = (Mon->1, Tue->1, Wed->1, Thu->1, Fri->1, Sat->0, Sun->0)
If we have a monoid (Int, 0, +), we can automatically extend this mapping to List[WeekDay]->Int
which counts the number of working days.
Reduce
reduce: List[A] → A
with properties:
(This defines an algebra over the functor List[_].)
This is exactly what we did on the previous page, reduce.
That's almost it
Monoids are simple, are not they?
Let's throw in more properties...
Commutative Monoids
a Op b == b Op a
e.g.
but not these:
Commutative Monoids
How can we create one?
e.g.
"abracadabra" -> "aaaaabbcdrr"
Order does not matter; numbers matter.
Free commutative monoid on A: a collection of possibly duplicates, order does not matter.
It is called Bag[A]
Commutative Monoids
Bag[A]
{
"partridges in a pear tree": 1,
"turtle doves": 2,
"french hens": 3,
"calling birds": 4,
"golden rings": 5
//etc
}
Commutative Monoids
How about sets?!
Commutative Monoids...
How about sets?!
x Op x == x : x is idempotent
Set('a','b','c') + Set('b','c','d') = Set('a','b','c','d')
Commutative Monoids...
How about sets?!
x Op x == x : x is idempotent
Set('a','b','c') + Set('b','c','d') = Set('a','b','c','d')
Finite set is a free commutative monoid where all elements are idempotent (thank you, Shachaf, for the hint)
another example
The Whole Picture
Bigger Picture
(source: Alexander Bunkenburg, "The Boom Hierarchy")
Questions... really?
Thank you!
(and thanks to my friends on livejournal for their critique)