Когда использовать `with` для ограничения параметров типа вместо` <: `или` <: <`в Scala? - PullRequest
5 голосов
/ 13 декабря 2011

В другой вопрос , я советую использовать with в месте, где обычно используется <: или <:<.Таким образом, вместо определения функций любым из следующих двух способов:

scala> def f[A,C <: Seq[A]](xs: C) = 0
f: [A, C <: scala.collection.immutable.Seq[A]](xs: C)Int

scala> f(List(1))
<console>:54: error: inferred type arguments [Nothing,List[Int]] do not conform to method f's type parameter bounds [A,C <: scala.collection.immutable.Seq[A]]
              f(List(1))
              ^

scala> implicit def f[A,C](xs: C)(implicit ev: C <:< Seq[A]) = new { def foo = 0 }
f: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Seq[A]])java.lang.Object{def foo: Int}

scala> List(0) foo
<console>:54: error: Cannot prove that List[Int] <:< scala.collection.immutable.Seq[A].
              List(0) foo
                  ^

scala> f(List(0)) foo
res17: Int = 0

Можно сделать:

scala> implicit def f[A,C](xs: C with Seq[A]) = new { def foo = 0 }
f: [A, C](xs: C with scala.collection.immutable.Seq[A])java.lang.Object{def foo: Int}

scala> List(0) foo
res18: Int = 0

Мой вопрос: помимо вышеупомянутого конкретного случая, когда следует использовать with вместо <: или <:< для параметра типа?Почему бы не всегда использовать вместо этого with?Я ищу обсуждение нюансов среди альтернатив здесь.Благодаря.

1 Ответ

9 голосов
/ 13 декабря 2011

Значения совершенно разные.C <: Seq[A] означает, что C является подтипом Seq[A], как вы знаете;xs: C with Seq[A] не накладывает никаких ограничений на C, но означает, что xs должно быть и C, и Seq[A].Поэтому обычно вы должны использовать тот, который вы на самом деле имеете в виду.

В def f[A,C <: Seq[A]](xs: C) проблема в том, что компилятор Scala не может вывести A, поскольку он явно не указан в типе аргументов.Я не вижу никакой причины в принципе, это не может сделать вывод A;это просто не в настоящее время.Замена типа на C with Seq[A] означает, что A теперь появляется в типе xs и позволяет компилятору выводить A.Таким образом, если вы действительно имеете в виду ограничение, но A подразумеваете вывод, вам на самом деле нужно написать

implicit def f[A,C <: Seq[A]](xs: C with Seq[A])

вместо вашего третьего определения, и это то, что делает ответ на связанный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...