class A | |
class A2 extends A | |
class B | |
trait M[X] | |
// | |
// Upper Type Bound | |
// | |
def upperTypeBound[AA <: A](x: AA): A = x | |
// equivalently, require a implicit parameter of <:<[AA, A]. | |
// This technique must be used if A is an abstract type from the | |
// enclosing scope. | |
def upperTypeBound2[AA](x: AA)(implicit ev: AA <:< A): A = x // compiles to ev(x) | |
// | |
// Lower Type Bound | |
// | |
def lowerTypeBound[AA >: A](x: AA, pred: (AA => Boolean)): Boolean = pred(x) | |
// equivalently, require a implicit parameter of <:<[A, AA]. | |
// This technique must be used if A is an abstract type from the | |
// enclosing scope. | |
def lowerTypeBound2[AA >: A](x: AA, pred: (AA => Boolean))(implicit ev: A <:< AA): Boolean = pred(x) | |
// | |
// View Bound | |
// | |
def viewBound[AA <% A](x: AA): A = x | |
//compiles to: | |
def viewBound$[AA](x: AA)(implicit ev1$ : AA => A) = ev1$(x) | |
// | |
// Context Bound | |
// | |
def contextBound[X: M](x: X) = x; | |
//compiles to: | |
def contextBound$[X](x: X)(implicit ev1$ : M[X]) = x | |
// In combination: | |
def combo[AA <: A >: B <% String <% Int : M : Ordering] = 0 | |
// compiles to: | |
def combo[AA >: B <: A](implicit | |
evidence$1: (AA) => String, | |
evidence$2: (AA) => Int, | |
evidence$3: M[AA], | |
evidence$4: Ordering[AA] | |
): Int = 0 | |
// | |
// Usage | |
// | |
{ | |
{ | |
upperTypeBound(new A) | |
upperTypeBound(new A2) | |
} | |
{ | |
val predA = (a: A) => true | |
val predAny = (a: Any) => true | |
lowerTypeBound(new A, predA) | |
lowerTypeBound(new {}, predAny) | |
} | |
{ | |
implicit def String2A(s: String): A = new A | |
viewBound("") | |
} | |
{ | |
implicit def MofA: M[A] = new M[A] {} | |
contextBound(new A) | |
} | |
} |
Great summary and reference. It shows that multiple view and context bounds are possible, but this does not work with upper bounds and lower bounds. I believe multiple upper bounds can be specified with with
: [A <: B with C], and multiple lower bounds are discussed there: http://stackoverflow.com/questions/6117999/multiple-lower-type-bounds-in-scala
Could you add such examples for completeness's sake?
I'd like to see some example of "abstract type from the enclosing scope".
Me, too! ("I'd like to see some example of "abstract type from the enclosing scope")
trait M[A] {
def a: A
def inc(implicit A <:< Int): Int = 1 + a
}
Thanks!
A little bug, though ;-)
Fixed:
trait M[A] {
def a: A
def inc(implicit ev: A <:< Int): Int = 1 + a
}```
I know this Gist is pretty old, but just to point out for further audience... A <% B
(view bound) has been deprecated in Scala 2.11. Check SI-7629 issue and discussion for more details.
this is the very definition of "screwy"...