Skip to content

Instantly share code, notes, and snippets.

@einblicker
Created February 6, 2012 23:20
Show Gist options
  • Save einblicker/1755825 to your computer and use it in GitHub Desktop.
Save einblicker/1755825 to your computer and use it in GitHub Desktop.
object TypesafeFormatter {
sealed abstract class Dir[A, B] {
def format : (String => A) => (String => B)
}
def l[A](s: String): Dir[A, A] = L[A](s)
case class L[A](s: String) extends Dir[A, A] {
def format = {
(cont: String => A) =>
(out: String) =>
cont(out + s)
}
}
def i[A]: Dir[A, Int => A] = I[A]()
case class I[A]() extends Dir[A, Int => A] {
def format = {
(cont: String => A) =>
(out: String) =>
(i: Int) => cont(out + i.toString)
}
}
def s[A]: Dir[A, String => A] = S[A]()
case class S[A]() extends Dir[A, String => A] {
def format = {
(cont: String => A) =>
(out: String) =>
(s: String) => cont(out + s)
}
}
case class C[A, B, C, D](d1: Dir[A, B], d2: Dir[C, A]) extends Dir[C, B] {
def format = {
(cont: String => C) =>
(out: String) =>
d1.format.apply(d2.format.apply(cont)).apply(out)
}
}
implicit def cInfix[A, B](d1: Dir[A, B]) = new {
def ^[C](d2: Dir[C, A]): Dir[C, B] =
C(d1, d2)
}
def format[A](d: Dir[String, A]) = {
d.format(identity)("")
}
def test = {
import TypesafeFormatter._
//残念ながら型推論はしてくれない…
println(format(l[String => String]("hello ") ^ s ^ l("!!"))("world"))
println(format(l[Int => Int => Int => String]("a:") ^ i ^ l(" b:") ^ i ^ l(" c:") ^ i)(1)(2)(3))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment