Проблема эквивалентности типов при использовании зависимых типов методов и проекций типов - PullRequest
2 голосов
/ 30 января 2012

Я пытаюсь сделать следующее с Scala 2.10.0-M1:

trait Container {
  type X
}

class Test[C <: Container](val c: C) {
  def foo(x: c.X): C#X = x // this compiles fine
  def bar(x: C#X): c.X = x // this does not compile
}

Проблема при использовании этой формы та же:

def bar[C <: Container](c: C)(x: C#X): c.X = x

Я не оченьпонять, почему foo компилируется, а bar нет.

Я считаю, что c.X и C#X здесь должны быть одинаковыми.

Кроме того, я не понимаю ошибкусообщение:

[error]  found   : x.type (with underlying type C#X)
[error]  required: Test.this.c.X
[error]  possible cause: missing arguments for method or constructor
[error]   def bar(x: C#X): c.X = x // this does not compile

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 30 января 2012

C#X означает X из любого C. c.X означает X от вашего конкретного C, а именно c. Последнее гораздо конкретнее!

Например, если X - это счет, а c - конкретный клиент, c.X означает, что метод принимает счета только от (для, предположительно) клиента c. C#X означает, что он принимает любой счет от любого клиента. Если вы хотите, чтобы клиенты оплачивали только свои счета (по крайней мере, по умолчанию), вам нужен первый вариант.

3 голосов
/ 30 января 2012

@ Рекс дал хорошее объяснение того, что случилось. Вот как вы можете это исправить ...

Если разумно иметь возможность вернуть x как результат типа c.X (т. Е. Значение типа X конкретного c, переданного в качестве аргумента, вы можете ужесточить его тип в качестве аргумента

def bar[C <: Container](c: C)(x: c.X): c.X = x

Теперь бар будет принимать только значения типа X, относящиеся к конкретному значению c. Если это не сработает для вас на сайтах по вызову бара, вам нужно будет переделать свой дизайн.

2 голосов
/ 30 января 2012

c.X и C#X однозначно не одно и то же - если бы они были, почему оба существовали бы?

Рассмотрим случай, когда у вас есть a и b, разные экземпляры C.По определению a.X и b.X различны, но оба C#X.

...