Created
November 8, 2009 08:02
-
-
Save retronym/229163 to your computer and use it in GitHub Desktop.
Demo of generalised type constraints in Scala 2.8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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] | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It comes in handy when pimping generic types, e.g: