Demo of generalised type constraints in Scala 2.8
// scala 2.7 simple type constraint. This can only constrain a type parameter of this function. | |
// Below, in ListW.sumint28, we can't use this approach because we want to constrain T, | |
// a type param of the enclosing trait. | |
def sumint27A[T <: Int](l: List[T]) : Int = l.reduceLeft((a: Int, b: Int) => a + b) | |
trait IntLike[X] extends (X => Int) | |
object IntLike { | |
implicit val intIntLike: IntLike[Int] = new IntLike[Int] { def apply(x: Int) = identity(x) } | |
} | |
trait ListW[T] { | |
val l: List[T] | |
// T can be constrained within the context of this function by requiring an implicit parameter | |
// to certify that it is IntLike. | |
def sumint27B(implicit ev: IntLike[T]) : Int = l.map(ev).reduceLeft(_ + _) | |
// In scala 2.8, we can require an implicit parameter of type T <:< Int (that is, <:<[T, Int]) | |
// The compiler will provide this if T conforms to Int. The parameter `ev` can be used to | |
// safely cast a value T to Int. | |
def sumint28(implicit ev: T <:< Int) : Int = l.map(ev).reduceLeft(_ + _) | |
} | |
implicit def ListW[T](list: List[T]): ListW[T] = new ListW[T] { | |
val l = list | |
} | |
val intList = List(1, 2, 3) | |
val stringList = List("1", "2", "3") | |
sumint27A(intList) | |
{ | |
import IntLike._ | |
intList.sumint27B | |
} | |
intList.sumint28 | |
/* Compiler errors: | |
sumint27A(stringList) // type arguments [java.lang.String] do not conform to method sumint27's type parameter bounds [T <: Int] | |
stringList.sumint27 // compile error: could not find implicit value for parameter ev: IntLike[Any] | |
stringList.sumint28 // compile error: could not find implicit value for parameter ev: <:<[java.lang.String,Int] | |
*/ |
This comment has been minimized.
This comment has been minimized.
It comes in handy when pimping generic types, e.g: class Tuple2W[A, B](t2: (A, B)) { def toSeq[C](implicit ac: A <:< C, bc: B <: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Just out of curiosity, when would you use this sort of subclassing constraint rather than a type class?