Skip to content

Instantly share code, notes, and snippets.

@OlegIlyenko
Created December 7, 2012 18:33
Show Gist options
  • Select an option

  • Save OlegIlyenko/4235329 to your computer and use it in GitHub Desktop.

Select an option

Save OlegIlyenko/4235329 to your computer and use it in GitHub Desktop.
Type classes
package org.am.incident
object Test extends App {
def ??? = throw new IllegalStateException()
trait Conv[A, B] {
def conv(a: A): B
}
trait Cal {
type C <: Cal
def +[T](c: T)(implicit ev: Conv[T, C]): C = {
val cOfMyType = ev.conv(c)
// ...
this.asInstanceOf[C]
}
def toCal[A](implicit ev: Conv[C, A]) = ev.conv(this.asInstanceOf[C])
}
object Cal {
implicit def conv[T <: Cal] = new Conv[T, T] {
def conv(a: T): T = {
println(a.getClass + " T -> T")
a
}
}
implicit def convab[A <: Cal, B <: Cal](implicit ev1: Conv[A, RCal], ev2: Conv[RCal, B]) = new Conv[A, B] {
def conv(a: A): B = {
println(a.getClass + " -> B")
val ref = ev1.conv(a)
ev2.conv(ref)
}
}
}
trait Booo {
}
class GCal extends Cal{
type C = GCal
}
object GCal {
implicit val convto = new Conv[GCal, RCal] {
def conv(a: GCal): RCal = {
println("G -> R")
new RCal
}
}
implicit val convtoh = new Conv[GCal, HCal] {
def conv(a: GCal): HCal = {
println("G -> H opt")
new HCal
}
}
implicit val convfrom = new Conv[RCal, GCal] {
def conv(a: RCal): GCal = {
println("R -> G")
new GCal
}
}
}
class HCal extends Cal {
type C = HCal
}
object HCal {
implicit val convto = new Conv[HCal, RCal] {
def conv(a: HCal): RCal = {
println("H -> R")
new RCal
}
}
implicit val convfrom = new Conv[RCal, HCal] {
def conv(a: RCal): HCal = {
println("R -> H")
new HCal
}
}
}
class RCal extends Cal {
type C = HCal
}
val gcal = new GCal
val hcal = new HCal
val res: HCal = hcal + gcal
// val res: GCal = gcal + gcal
println(res)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment