What are Scala <: <, =: = and <% <classes?

Possible duplicate:
What to do <: <, <% <, and =: = average in Scala 2.8 and where are they documented?

I'm curious because I saw them in the Scala library code, but it was pretty hard for me to say something about them to Google, because their names are not words.

+4
source share
3 answers

These classes are used for implicit parameters that limit the applicability of the method. The following is a description of each class. In general, they are useful for restricting a type parameter of an enclosing class in 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 the type parameter list.

This can be useful if you want to add an additional constraint for the class type parameter in the context of a particular method. For example, the Foo class below can be used with any type, but the bar method is valid only 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. It does not have equivalent syntax in the list of type parameters, you just have to use the same type parameter twice.

This can be used in the same way as <:< , except that it requires the types to match exactly. This can be used to make a couple 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 a type parameter is more specific than a constraint, you can force a more specific method.

<%<[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 the type parameter list.

This requires an implicit function to turn A into B. This will always be possible if A <: B , since the implicit A <:< B satisfies this restriction.

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

+10
source

<:< , =:= and <%< are common classes, all of which with two type parameters, and all of them extend Function1 (function with one argument). They are defined in Predef . They are designed to provide a very simple conversion as implicits. Conversions are so basic that most of the time they are identical. The point of having these classes, not functions, is that they can be distinguished from other functions that may be in implicit domains. Predef gives the following implicit

  • For each type A , a <:<[A,A] . Since <:< [-From, +To] , <:<[A,A] will satisfy any <:<[A,B] , where A corresponds to B realization is identity.
  • For each type A there also exists =:=[A,A] , but =:= is invariant, so it does not satisfy any A =:= B if A is not exactly B. the implementation is identical
  • Each time A <% B , A <%< B exists. Implementation implied A <% B

The point is not to provide smart conversions (the identity is not too smart), but to provide a level at the library level, it is necessary to enforce some input restriction at compile time, similar to the language level restriction <:, <% and the simple absence of an argument of type (which also a pretty strong restriction) in places where language restrictions are not available. A typical example is in a generic class when you want a method to be available only for some type parameter value. Suppose Collection [A], and I want the method sorting to be available only if A <: Ordered [A]. I don’t want to put a restriction in the class declaration because I want to accept collections whose elements are not ordered. I just don't want them to have a sort method. I cannot set a restriction on the sort method, because A is not even displayed as a parameter of the sort type of the method. & L ;: <provides a solution:

 class MyCollection[A] { def sort(implicit ev: A <:< Ordered[A]) // other methods, without constraints } 

By doing this, sorting is technically available in all instances of MyCollection, but practically when it does not pass the ev parameter explicitly, it will look for A <:< Ordered[A] in the implicit region, and conforms in the predef will give only one if A is a subtype of Ordered[A] . Since the conversion (identity) between A and Ordered[A] becomes available in the implicit scope of the subroutine, A will be used as an Ordered[A] in the sort body of the method.

Using =:= will cause the type to be precisely ordered [A] (the equivalent restriction on MyCollection would be to just make it not generic, and put that type wherever there is a generic parameter). <%< will provide implicit conversion. That would be more likely here.

Actually for this particular sorting method, the correct solution would be to get Ordering[A] in an implicit context with def sort(implicit ev: Ordering[A]) , but that would not show the point of these classes.

+4
source

They are generalized type constraints for type arguments. Familiarize yourself with their definitions along with the corresponding implicit matching methods () in Predef.

In short, it works as follows:

  • you add an implicit parameter to your method, for example implicit tc: T <:< U , which works like implicit tc: <:<[T, U]
  • there is an implicit conforms() method that returns the required instance, which ensures that T <: U (exactly the same as with regular generics)
  • if T <: U is wrong, compilation of the method call ends with "implicit not found"

See a usage example here: http://java.dzone.com/articles/using-generalized-type

+1
source

All Articles