Skip to content

Instantly share code, notes, and snippets.

@jedws
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedws/9145688 to your computer and use it in GitHub Desktop.
Save jedws/9145688 to your computer and use it in GitHub Desktop.
attempts to use path dependent types to do automatic type mapping
scala> import To._
import To._
scala> val f: Int => Int = _ + 1
f: Int => Int = <function1>
scala> f.toJava
res0: To.Function[Integer,Integer] = To$$anon$3$$anonfun$to$2$$anon$4@583f2b6b
scala> res0.toScala
res1: Int => Int = <function1>
object To {
trait Bijection[A, B] {
def to: A => B
def from: B => A
}
sealed trait Translate[A] {
type T
def apply(a: A): T
}
sealed trait To[A] extends Translate[A]
sealed trait From[A] extends Translate[A]
implicit def BijectionTo[A, B](implicit map: Bijection[A, B]) =
new To[A] {
type T = B
def apply(a: A): T = map.to(a)
}
implicit def BijectionFrom[A, B](implicit map: Bijection[A, B]) =
new From[B] {
type T = A
def apply(a: B): A = map.from(a)
}
implicit class ToJavaSyntax[A](a: A) {
def toJava(implicit to: To[A]): to.T = to(a)
}
implicit class ToScalaSyntax[A](a: A) {
def toScala(implicit from: From[A]): from.T = from(a)
}
implicit object IntToInteger extends Bijection[Int, Integer] {
def from = _.toInt
def to = _.toInt
}
trait Function[A, B] {
def apply(a: A): B
}
implicit def FunctionBijection[A1, A2, B1, B2](implicit A: Bijection[A1, A2], B: Bijection[B1, B2]) =
new Bijection[(A1 => B1), Function[A2, B2]] {
def to: (A1 => B1) => Function[A2, B2] =
f =>
new Function[A2, B2] {
def apply(a: A2) = B.to(f(A.from(a)))
}
def from: Function[A2, B2] => (A1 => B1) =
f => a => B.from(f(A.to(a)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment