Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Context bounds with two generic parameters

In Scala, I can use context bounds:

def sort[T : Ordered](t: Seq[T])

To mean the same thing as:

def sort[T](t: Seq[T])(implicit def Ordered[T])

What if I have a class with two generic parameters. I.e. I want to be able to ensure that I have a Writer[T, String]. Is there a syntax where I can use context bounds (T : ...) or do I need to have the implicit explicitly (that was fun to write).

like image 865
schmmd Avatar asked Nov 21 '13 20:11

schmmd


1 Answers

Yes, it's possible! But not really very pretty:

trait Writer[T, O] {
  def write(t: T): O
}

def writeToString[T: ({ type L[x] = Writer[x, String] })#L](t: T) =
  implicitly[Writer[T, String]].write(t)

implicit object intToStringWriter extends Writer[Int, String] {
  def write(t: Int) = t.toString
}

And then:

scala> writeToString(1)
res0: String = 1

The ({ type L[x] = Writer[x, String] })#L thing is called a type lambda. Sometimes they're very convenient (if buggy), but this definitely isn't one of those times. You're much better off with the explicit implicit.

like image 137
Travis Brown Avatar answered Oct 25 '22 18:10

Travis Brown