Friday, January 8, 2016

Monoid in scala

The monoid typeclass:

/**
  * Created by kaiyin on 1/8/16.
  */

object M {

  trait Monoid[A] {
    def append(a1: A, a2: A): A

    def empty: A
  }

  object Monoid {
    implicit def ListMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {
      def append(a1: List[A], a2: List[A]) = a1 ::: a2

      def empty = Nil
    }

    implicit def PairMonoid[A, B](implicit a: Monoid[A], b: Monoid[B]): Monoid[(A, B)] = new Monoid[(A, B)] {
      def append(ab1: (A, B), ab2: (A, B)) = (a.append(ab1._1, ab2._1), b.append(ab1._2, ab2._2))
      def empty = (a.empty, b.empty)
    }

    def append[A](a1: A, a2: A)(implicit m: Monoid[A]): A = m.append(a1, a2)
    def empty[A](implicit m: Monoid[A]) = m.empty
  }
}

import M.Monoid._
import M.Monoid

implicitly[Monoid[List[Int]]].append(List(1, 2), List(3, 4))

append(List(1, 2), List(3, 4))
append(List(List(1), List(2)), List(List(3), List(4)))
empty[List[String]]
append((List(1, 2), List(5, 6)), (List(3, 4), List(7, 8)))

0 comments: