Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Scala <:<, =:= and <%< classes for? [duplicate]

Tags:

scala

Possible Duplicate:
What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?

I'm curious since I saw them in Scala library code, but I found it quite hard to Google something about them since their names are not words.

like image 985
Karel Smutný Avatar asked Dec 07 '22 20:12

Karel Smutný


1 Answers

These classes are used for implicit parameters that restrict the applicability of a method. Below is a description of each class. In general they are useful to restrain the a type parameter of an enclosing class within the context of a single method.

<:<[A,B] or A <:< B

The compiler can provide an implicit instance of this type only when A is a subtype of B. This is similar to A <: B in a type parameter list.

This can be useful when you want to put an additional constraint on a class type parameter in the context of a particular method. For example the class Foo below can be used with any type, but the method bar is only valid when T is a subtype of Number.

class Foo[T](x: T) {
  // In general T could be any type
  def bar(implicit ev: T <:< Number) = {
    // This method can now only be used when T is a subtype of Number
    // also, you can use ev to convert a T to number
    ev(x).doubleValue
  }
}

new Foo(123 : java.lang.Integer).bar // returns 123.0: Double
new Foo("123").bar // compile error: Cannot prove java.lang.String <:< java.lang.Number

=:=[A,B] or A =:= B

The compiler can provide an implicit instance of this type only when A is the same type as B. This doesn't have an equivalent syntax in a type parameter list, you'd just use the same type parameter twice.

This can be used much like <:< except that it requires the types to match exactly. This could be used to make a pair of methods mutually exclusive.

class Foo[T<:Number](x:T) {
  def numOnly(implicit ev: T =:= Number) = ()
  def floatOnly(implicit ev: T =:= Float) = ()
}

val asFloat = new Foo(123.0f:java.lang.Float)
asFloat.numOnly // Compile error
asFloat.floatOnly // Ok
val asNum = new Foo(123.0f:java.lang.Number)
asFloat.floatOnly // Ok
asFloat.numOnly // Compile error

Essentially if the type parameter is more specific than the constraint you can force the more specific method to be used.

<%<[A,B] or A <%< B

The compiler can provide an implicit instance of this type only when A can be converted to B. This is similar to A <% B in a type parameter list.

This requires that there is an implicit function available to turn an A into a B. This will always be possible when A <: B since the implicit A <:< B satisfies this constraint.

This class is actually marked as deprecated. It says you should instead just use A => B.

like image 179
Geoff Reedy Avatar answered Dec 23 '22 13:12

Geoff Reedy