Skip to content

Instantly share code, notes, and snippets.

@folone
Last active December 13, 2015 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save folone/4988767 to your computer and use it in GitHub Desktop.
Save folone/4988767 to your computer and use it in GitHub Desktop.
// Haskeller
trait Monoid[T] {
val id: T
def op: T => T => T
}
// Agdaista
trait Monoid[T] {
val `∅`: T
def `∙`: T ⇒ T ⇒ T
// since scala 2.11, using some shapeless magic (https://gist.github.com/folone/4945168)
//implicit val leftId: ^(∅ ∙ x) = x
//implicit val rightID: ^(x ∙ ∅) = x
}
// ML-dev
trait Monoid {
type T
val id: T
def op: (T, T) => T
}
// Hardcore ML-dev
type MONOID = {
type T
val id: T
def op: (T, T) => T
}
// Java-guy, after reading about self-types
trait Monoidal[T] { this: T =>
def op(x: T): T
}
// Java-guy, after reading about implicit views
abstract class MonoidEnriched[T] {
def op(y: T): T
}
// Java-guy, after reading about typeclasses
trait Monoid[T] {
val id: T
def op(x: T, y: T): T
}
// Java-guy, after reading about currying and partial application
trait Monoid[T] {
val id: T
def op(x: T)(y: T): T
}
// Haskeller
implicit def list[T] = new Monoid[List[T]] {
val id = Nil
def op = xs => xs ++ _
}
// ML-dev
implicit def list[E] = new Monoid {
type T = List[E]
val id = Nil
def op = _ ++ _
}
// Hardcore ML-dev
implicit def list[E]: MONOID { type T = List[E] } = new {
type T = List[E]
val id = Nil
def op = _ ++ _
}
// Java-guy, after reading about self-types
class MonoidalListAdapter[T](val list: List[T]) extends Monoidal[MonoidalListAdapter[T]] {
def op(x: MonoidalListAdapter[T]) = new MonoidalListAdapter[T](list ++ x.list)
}
// Java-guy, after reading about implicit views
abstract class ListMonoidEnriched[T](x: List[T]) extends MonoidEnriched[List[T]] {
def op(y: List[T]) = x ++ y
}
implicit def list[T](l: List[T]) = new ListMonoidEnriched(l)
// Java-guy, after reading about implicit classes
implicit class ListMonoidEnriched[T](x: List[T]) extends MonoidEnriched[List[T]] {
def op(y: List[T]) = x ++ y
}
// Java-guy, after reading about typeclasses
implicit def list[T] = new Monoid[List[T]] {
val id = Nil
def op(x: List[T], y: List[T]) = x ++ y
}
// Java-guy, after reading about currying and partial application
implicit def list[T] = new Monoid[List[T]] {
val id = Nil
def op(x: List[T])(y: List[T]) = x ++ y
}
// Typeclass-guys
def f[M](xs: M)(implicit m: Monoid[M]) = m.op(xs, xs) // или m.op(xs)(xs)
// Hardcore ML-dev
def f[M](xs: M)(implicit m: MONOID { type T = M }) = {
import m._
op(xs, xs)
}
// Java-guy, after reading about self-types
def f[M <: Monoidal[M]](xs: M) = xs.op(xs)
// Implicit views and classes guys
def f[M <% MonoidEnriched[M]](xs: M) = xs.op(xs)
@tonymorris
Copy link

They all suffer from failure to split the binary operation. The realisation of the importance of this comes about from having a background in application development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment