1

I was recently playing with monoids in Standard ML. The signature is easy to write:

signature MONOID =
sig
  type monoid
  val neutral : monoid
  val combine : monoid -> monoid -> monoid
end

And so are simple monoids, such as an integer addition monoid:

structure IntSumMonoid : MONOID =
struct
  type monoid = int
  val neutral = 0
  fun combine a b = a + b
end

But I got stuck at defining a monoid for a higher-kinded type, such as list. This won't compile, of course:

structure ListMonoid : MONOID =
struct
  type monoid = 'a list
  val neutral = []
  fun combine a b = a @ b
end

After some searching I've found the following solution, based on a functor:

functor ListMonoid (type m) : MONOID =
struct
  type monoid = m list
  val neutral = []
  fun combine a b = a @ b
end

My question is whether there exists an alternative for declaring a generic list monoid, ideally one that doesn't require a functor declaration. It's obviously unnecessary to know the contained type of a list when trying to declare a list monoid.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202

1 Answers1

1

You can parameterize the type in the signature. But composing monoids then becomes odd or impossible. Haskell solves this using type classes, which you can emulate in SML with functors, but the syntax is heavy (as you've noticed).

signature MONOID =
sig
  type 'a monoid
  val neutral : 'a monoid
  val combine : 'a monoid -> 'a monoid -> 'a monoid
end

structure IntSumMonoid : MONOID =
struct
  type 'a monoid = int
  val neutral = 0
  fun combine a b = a + b
end

structure ListMonoid : MONOID =
struct
  type 'a monoid = 'a list
  val neutral = []
  fun combine a b = a @ b
end

The paper that describes the translation is http://www.mpi-sws.org/~dreyer/papers/mtc/main-short.pdf

seanmcl
  • 9,740
  • 3
  • 39
  • 45