Skip to content

Instantly share code, notes, and snippets.

@bkyrlach
Created October 11, 2012 18:28
Show Gist options
  • Select an option

  • Save bkyrlach/3874518 to your computer and use it in GitHub Desktop.

Select an option

Save bkyrlach/3874518 to your computer and use it in GitHub Desktop.
Shouldn't this compile?
abstract class Tree[+A]
case class Node[A](l: Tree[A], e: A, r: Tree[A]) extends Tree[A]
case object Tip extends Tree[Nothing]
abstract class MONOID {
type t
val append: t => t => t
val identity: t
}
object IntMonoid extends MONOID {
type t = Int
val append: Int => Int => Int = a => b => a + b
val identity = 0
}
object StringMonoid extends MONOID {
type t = String
val append: String => String => String = a => b => a + b
val identity = ""
}
abstract class FOLDABLE {
type hk[_]
def foldm[el](i: el)(f: el => el => el)(x: hk[el]): el
}
object FoldableList extends FOLDABLE {
type hk[_] = List[_]
override def foldm[el](i: el)(f: el => el => el)(x: List[el]): el = x match {
case Nil => i
case h::t => foldm(f(i)(h))(f)(t)
}
}
object FoldableTree extends FOLDABLE {
type hk = Tree[_]
override def foldm[el](i: el)(f: el => el => el)(x: Tree[el]): el = x match {
case Tip => i
case Node(l, e, r) => foldm(foldm(f(i)(e))(f)(l))(f)(r)
}
}
class Summation(val M: MONOID, FM: FOLDABLE) {
def sum(x: FM.hk[M.t]): M.t = FM.foldm(M.identity)(M.append)(x)
}
object SumLInt extends Summation(IntMonoid, FoldableList)
object SumLString extends Summation(StringMonoid, FoldableList)
object SumTInt extends Summation(IntMonoid, FoldableTree)
object ModuleFun extends App {
FoldableList.foldm(IntMonoid.identity)(IntMonoid.append)(List(1,2,3,4))
println(SumLInt.sum(List(1,2,3,4)))
println(SumLString.sum(List("a", "b", "c", "d")))
println(SumTInt.sum(Node(Node(Tip, 3, Tip), 4, Node(Tip, 5, Tip))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment