Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<:< operator in scala

Tags:

scala

Can anybody provide some details on <:< operator in scala. I think:

if(apple <:< fruit)  //checks if apple is a subclass of fruit.

Are there any other explanations? I see many definitions in the scala source file.

like image 893
scout Avatar asked Apr 08 '10 19:04

scout


People also ask

What are the operators in Scala?

There are five relational operators in Scala: Greater than (>) Less than (<) Greater than or equal to (>=)

What does =!= Mean in Scala?

It has no special meaning whatsoever. It is also not a well-known method name in Scala. It seems to come from some library; you need to look at the documentation of whatever library you are using to figure out what it does.

What does :+ mean in Scala?

On Scala Collections there is usually :+ and +: . Both add an element to the collection. :+ appends +: prepends. A good reminder is, : is where the Collection goes. There is as well colA ++: colB to concat collections, where the : side collection determines the resulting type.

What is operator overloading in Scala?

Operator Overloading in Scala Scala supports operator overloading, which means that the meaning of operators (such as * and + ) may be defined for arbitrary types. Example: a complex number class: class Complex(val real : Double, val imag : Double) { def +(other : Complex) = new Complex( real + other.


3 Answers

The <:< type is defined in Predef.scala along with the related types =:= and <%< as follows:

// used, for example, in the encoding of generalized constraints
// we need a new type constructor `<:<` and evidence `conforms`, as 
// reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred)
// to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters)
// simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`)
// in part contributed by Jason Zaugg
sealed abstract class <:<[-From, +To] extends (From => To)
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x} // not in the <:< companion object because it is also intended to subsume identity (which is no longer implicit)

This uses the Scala feature that a generic type op[T1, T2] can be written T1 op T2. This can be used, as noted by aioobe, to provide an evidence parameter for methods that only apply to some instances of a generic type (the example given is the toMap method that can only be used on a Traversable of Tuple2). As noted in the comment, this generalizes a normal generic type constraint to allow it to refer to any in-scope abstract type/type parameter. Using this (implicit ev : T1 <:< T2) has the advantage over simply using an evidence parameter like (implicit ev: T1 => T2) in that the latter can lead to unintended in-scope implicit values being used for the conversion.

I'm sure I'd seen some discussion on this on one of the Scala mailing lists, but can't find it at the moment.

like image 163
Ben Lings Avatar answered Oct 23 '22 12:10

Ben Lings


<:< is not an operator - it is an identifier and is therefore one of:

  • the name of a type (class, trait, type alias etc)
  • the name of a method/val or var

In this case, <:< appears twice in the library, once in Predef as a class and once as a method on Manifest.

For the method on Manifest, it checks whether the type represented by this manifest is a subtype of that represented by the manifest argument.

For the type in Predef, this is relatively new and I am also slightly confused about it because it seems to be part of a triumvirate of identical declarations!

class <%<[-From, +To] extends (From) ⇒ To
class <:<[-From, +To] extends (From) ⇒ To
class =:=[From, To] extends (From) ⇒ To
like image 40
oxbow_lakes Avatar answered Oct 23 '22 12:10

oxbow_lakes


I asked around, and this is the explanation I got:

<:< is typically used as an evidence parameter. For example in TraversableOnce, toMap is declared as def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U]. This expresses the constraint that the toMap method only works if the traversable contains 2-tuples. flatten is another example. <:< is used to express the constraint that you can only flatten a traversable of traversables.

like image 14
aioobe Avatar answered Oct 23 '22 10:10

aioobe