Skip to content

Instantly share code, notes, and snippets.

@matsu-chara
Last active February 20, 2016 17:33
Show Gist options
  • Save matsu-chara/d0712a68a3b24a3ffe0c to your computer and use it in GitHub Desktop.
Save matsu-chara/d0712a68a3b24a3ffe0c to your computer and use it in GitHub Desktop.
FreeMagma
object FreeMagmaComponent {
import MagmaComponent._
// FreeMagmaの定義
sealed trait FreeMagma[A]
case class Var[A](a: A) extends FreeMagma[A]
case class Tree[A](a: FreeMagma[A], b: FreeMagma[A]) extends FreeMagma[A]
// インスタンス定義
implicit def magmaFreeMagmaInstance[A] = new Magma[FreeMagma[A]] {
override def o(m1: FreeMagma[A], m2: FreeMagma[A]): FreeMagma[A] = Tree(m1, m2)
}
// インタプリタの定義
def interpretMagma[A, B: Magma](f: (A => B), a: FreeMagma[A]): B = (f, a) match {
case (f, Var(a)) => f(a)
case (f, Tree(a, b)) => o(interpretMagma(f, a), interpretMagma(f, b))
}
}
object FreeMagmaTest {
import FreeMagmaComponent._
def main(args: Array[String]) {
val x: FreeMagma[String] = Tree(Var("a"), Tree(Var("a"), Var("b")))
val f: (String => Int) = {
case "a" => 1
case "b" => 2
}
// FreeMagmaの中身を取り出しながら、 String => Intな関数fを適用していく。
// fが適用されるとIntになるので、Magma[Int]を利用することができる。
// StringはMagmaとして扱っていないのに、FreeMagma[String]とするだけで、Magmaっぽいことができた!
val result = interpretMagma(f, x)
println(result) // 4
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment