Skip to content

Instantly share code, notes, and snippets.

@fedesilva
Forked from retronym/type-bounds.scala
Created September 14, 2010 23:04
Show Gist options
  • Select an option

  • Save fedesilva/579931 to your computer and use it in GitHub Desktop.

Select an option

Save fedesilva/579931 to your computer and use it in GitHub Desktop.
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)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment