Last active
August 29, 2015 13:56
-
-
Save jedws/9145688 to your computer and use it in GitHub Desktop.
attempts to use path dependent types to do automatic type mapping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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