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.