Skip to content

Instantly share code, notes, and snippets.

@mandubian
Last active January 26, 2017 07:18
Show Gist options
  • Save mandubian/f460e904754c89d4d437d7de319a8d83 to your computer and use it in GitHub Desktop.
Save mandubian/f460e904754c89d4d437d7de319a8d83 to your computer and use it in GitHub Desktop.
Function definition with multiple implicit blocks & Interleaving
object Test extends App {
implicit val b: String = "toto"
implicit val c: Float = 1.0F
trait Foo[A] {
type B
def AtoB(a: A): B
}
trait Bar[B] {
type C
def BtoC(a: B): C
}
implicit val foo = new Foo[Int] {
type B = String
def AtoB(s: Int): String = s.toString
}
implicit val bar = new Bar[String] {
type C = Float
def BtoC(s: String): Float = s.toFloat
}
// simple multi-block implicits
def f(a: Int)(implicit b: String)(implicit c: Float): String = a.toString + b + c.toString
// inter-dependent multi-block implicits
def g[A](a: A)(implicit foo: Foo[A])(implicit bar: Bar[foo.B]): bar.C = bar.BtoC(foo.AtoB(a))
// FOR EVALUATING THE CONCEPT: interleaved implicits/normal block
def h(a: Int)(implicit b: String)(c: Float): String = a.toString + b + c.toString
// FOR EVALUATING THE CONCEPT: interleaved+dependent implicits/normal block
def i[T](a: T)(implicit foo: Foo[T])(bar: Bar[foo.B]) = bar.BtoC(foo.AtoB(a)) //a.toString + b + c.toString
assert(f(5) == "5toto1.0")
assert(g(5) == 5.0F)
// See below function h/i calls:
// the middle implicit block is implicitly inferred to check that last param has right type
// this syntax with missing block can be questioned but the feature is really interesting
// because an implicit can be used to infer something about the next parameter (specially its type)
// and this could be extremely useful (if it doesn't prove to be an horror)
assert(h(5)(5.0f) == "5toto5.0")
assert(i(5)(bar) == 5.0F)
}
@vil1
Copy link

vil1 commented Jan 17, 2017

Bye bye Aux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment