Not an article, just some reflections on this idea…

You know what is a monoid?

  • a binary operation taking 2 elements and giving another element e x e -> e (aka a SemiGroup)
  • a Identity id element id . e = e . id = e (also called zero element)

(and some associativity)

In scalaz, here is the definition:

1
2
3
4
5
6
7
trait Monoid[F] extends Semigroup[F] { self =>
  ////
  /** The identity element for `append`. */
  def zero: F
  def append(f1: F, f2: => F): F
  ...
}

You can see the zero & the SemiGroup.append operations, right?

So you can write a Monoid[Int] or Monoid[List[A]] as those structures are monoids.

Now let’s consider HList the heterogenous List provided by Miles Sabin’s fantastic Shapeless. HList looks like a nice monoid.

1
(1 :: "toto" :: HNil) ++ (true :: HNil) => (1 :: "toto" :: true :: HNil)

What about writing a monoid for HList?

Scalaz monoid isn’t very helpful because our monoid operations would look like:

1
2
def zero: HNil.type
  def append(f1: H1 <: HList, f2: => H2 <: HList): H3 <: HList

So, to be able to write a Monoid of HList, we need something else based on multiple different types…

I spent a few hours having fun on this idea with Shapeless and tried to implement a Monoid for heterogenous structures like HList, Nat, Sized and even not heterogenous structures.

Here are the working samples.

Here is the code based on pseudo-dependent types as shapeless.

The signature of the HMonoid shows the zero and the Semigroup as expected:

1
trait HMonoid[A, B] extends HZero with HSemiGroup[A, B]

This is just a sandbox to open discussion on this idea so I won’t explain more and let the curious ones think about it…

Have Monoids of Fun!