Несколько нижних границ типа в Scala - PullRequest
12 голосов
/ 25 мая 2011

Я заметил, что tuple.productIterator всегда возвращает Iterator[Any], удивляясь, если невозможно установить несколько нижних границ (так что это может быть итератор наименьшего общего супертипа).

Я пытался инемного искал, но нашел только этот вопрос для нескольких верхних границ.

Это мой тест на определение типа итератора:

def f[A,B](a:A, b:B) = List(a,b)
// return type is List[Any]

def f[A,B, T >: A "and" T >: B](a:A, b:B) = List[T](a,b)
// doesn't compile, but
//  f(1, true) should give a List[AnyVal] and
//  f("x", "y") a List[String]

Является ли это ограничением JVM?


Редактировать: Вот несколько более крупный пример, который кажется нереализуемым при использовании подхода IttayD, когда T следует определить в методе:
class Foo[A, B](a: A, b: B) {
  def f[T >: A] = List[T](a) // works
  def g[T >: A "and" T >: B] = List[T](a) // doesn't work
}

Ответы [ 2 ]

10 голосов
/ 25 мая 2011

Для простого случая, когда A и B связаны компилятором в то же время, что и T, Ответ IttayD работает нормально:

def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)

КогдаA и B уже связаны, как в вашем примере class Foo[A, B], вам нужно ввести временные фиктивные переменные, чтобы компилятор выполнял эту работу:

class Foo[A, B](a: A, b: B) {
  def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}

(Радиясность: A1 >: A <: T означает, что тип A1 должен быть супертипом A и подтипом T, а не то, что A является подтипом обоих A1 и T.)

A1 и B1 здесь с единственной целью определить правильный тип для T.Если компилятор должен вывести их, они преобразуются в A1 = A и B1 = B, а затем T в качестве наиболее определенного типа, который является суперклассом A и B.

Одна вещь, которую компилятор не осознает, это то, что благодаря транзитивности у нас есть и T >: A, и T >: B, что следует непосредственно из ограничений относительно A1 и B1.Нам нужно помочь с надписями типов.

Теперь Product#productIterator не может использовать эту технику, так как она определена в месте, где мы даже не знаем A и B, или на самом делесколько параметров типа в конкретном подклассе.

4 голосов
/ 25 мая 2011

Похоже, вам нужен HList: http://apocalisp.wordpress.com/2010/07/06/type-level-programming-in-scala-part-6a-heterogeneous-list%C2%A0basics/

Чтобы ответить на конкретный вопрос:

scala> def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
f: [T, A <: T, B <: T](a: A, b: B)List[T]

scala> f(1, true)
res0: List[AnyVal] = List(1, true)

scala> f("x", "y")
res1: List[java.lang.String] = List(x, y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...