Instantly share code, notes, and snippets.

Embed
What would you like to do?
Tour of Scala Type Bounds
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)
}
}
@razie

This comment has been minimized.

Show comment
Hide comment
@razie

razie Aug 17, 2010

this is the very definition of "screwy"...

razie commented Aug 17, 2010

this is the very definition of "screwy"...

@jppellet

This comment has been minimized.

Show comment
Hide comment
@jppellet

jppellet Jun 11, 2011

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?

jppellet commented Jun 11, 2011

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?

@dcsobral

This comment has been minimized.

Show comment
Hide comment
@dcsobral

dcsobral Jun 22, 2011

I'd like to see some example of "abstract type from the enclosing scope".

dcsobral commented Jun 22, 2011

I'd like to see some example of "abstract type from the enclosing scope".

@hseeberger

This comment has been minimized.

Show comment
Hide comment
@hseeberger

hseeberger Jun 24, 2011

Me, too! ("I'd like to see some example of "abstract type from the enclosing scope")

hseeberger commented Jun 24, 2011

Me, too! ("I'd like to see some example of "abstract type from the enclosing scope")

@retronym

This comment has been minimized.

Show comment
Hide comment
@retronym

retronym Jun 24, 2011

trait M[A] {
   def a: A
   def inc(implicit A <:< Int): Int = 1 + a
}
Owner

retronym commented Jun 24, 2011

trait M[A] {
   def a: A
   def inc(implicit A <:< Int): Int = 1 + a
}
@hseeberger

This comment has been minimized.

Show comment
Hide comment
@hseeberger

hseeberger Jun 24, 2011

Thanks!
A little bug, though ;-)
Fixed:

trait M[A] {
   def a: A
   def inc(implicit ev: A <:< Int): Int = 1 + a
}```

hseeberger commented Jun 24, 2011

Thanks!
A little bug, though ;-)
Fixed:

trait M[A] {
   def a: A
   def inc(implicit ev: A <:< Int): Int = 1 + a
}```
@falconepl

This comment has been minimized.

Show comment
Hide comment
@falconepl

falconepl Sep 23, 2014

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.

falconepl commented Sep 23, 2014

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.

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