В приведенном ниже примере я хочу определить метод contains
, который не компилируется, если a
и b
не относятся к одному и тому же базовому типу.
- В
contains1
impl, еслиa
равноSeq[Int]
, а b равноString
,T
выводится какAny
и компилируется. Это не я хочу. - В
contains2
impl, еслиa
равноSeq[Int]
, а b равноString
, то он не компилируется. Поведение такое, какое я хочу.
def contains1[T](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains1(Seq(1,2,3), "four")) // false
def contains2[T: Ordering](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains2(Seq(1,2,3), "four")) // compilation error
// cmd7.sc:1: No implicit Ordering defined for Any.
// val res7 = isMatched(Seq(1,2,3), "s")
^
// Compilation Failed
Однако есть ли более простой способ добиться того же поведения, что и в contains2
? Ordering
контекстная привязка меня смущает, поскольку этот метод вообще не имеет ничего общего с сортировкой/упорядочением.
def contains[T](a: Seq[T])(b: T): Boolean = a.contains(b)
. В этом случае, поскольку b находится в отдельном списке аргументов, он не учитывается при выводе параметра типа T, в действительности уже выведенный тип T используется как таковой, еслиb
не того же типа, что и элементы в коллекции, он не будет компилироваться. - Дополнительно один совет, добавьте флаг-Xlint:infer-any
. - person Luis Miguel Mejía Suárez   schedule 17.06.2019def contains2[T: Eq](a: Seq[T], b: T): Boolean = a.exists(Eq[T].eqv(b, _))
с CatsEq
, где ограничение имеет смысл и фактически используется в операции. (К сожалению, уAny
есть экземплярscala.math.Equiv
, так что здесь это бесполезно.) - person Travis Brown   schedule 17.06.2019