Тип <:<
определен в Predef.scala вместе со связанными типами =:=
и <%<
следующим образом:
// 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)
Здесь используется функция Scala, позволяющая записать общий тип op[T1, T2]
T1 op T2
. Это может использоваться, как отмечено aioobe, для предоставления параметра доказательства для методов, которые применяются только к некоторым экземплярам универсального типа (приведенный пример - метод toMap
, который можно использовать только для Traversable
из Tuple2
). Как отмечено в комментарии, это обобщает обычное ограничение универсального типа, чтобы позволить ему ссылаться на любой абстрактный тип / параметр типа в области видимости. Использование этого (implicit ev : T1 <:< T2
) имеет преимущество перед простым использованием параметра подтверждения, такого как (implicit ev: T1 => T2
), в том, что последний может привести к непреднамеренным неявным значениям в области действия, используемым для преобразования.
Я уверен, что видел какое-то обсуждение этого вопроса в одном из списков рассылки Scala, но пока не могу его найти.