Reflexive Interfaces in Go

In languages with typeclasses, like Rust, or Haskell, you can have an interface that uses its type in different positions, like:

class Group a where
  unit :: a
  combine :: a -> a -> a
  invert :: a -> a

In Go, on the other hand, you can only really enforce some type as the “first argument”, e.g.:

type Consumer interface {
  Consume(string)
}

There are many situations where you’d want to be able to reference the type implementing an interface, for example when representing concepts from algebra.

One not very type-safe way of doing this is casting:

type Group interface {
  Combine(that Group) Group
  Invert() Group
}

Then, when implementing this for a concrete group, you’d cast to the right type:

func (x *mygroup) Combine(that Group) {
  casted := that.(*mygroup)
  ...
}

The idea is that you never mix different instances of Group together.

With generics, you’d be able to do something more type-safe:

type Group[T] interface {
  Combine(that T) T
  Invert() T 
}

And then consistently doing:

func foo[T Group[T]](x T) {
  ...
}

To ensure that the types lign up as desired.

One problem with both of these approaches is that there’s no way to model nullary operations, like:

unit :: a

I still don’t really know of a good way to model something like this in Go.