Ошибка в системе типов Scala? - PullRequest
5 голосов
/ 06 января 2011

Следующий код scala представляется правильным:

class A[X]
class C[M[X] <: A[X]]

class Main

new C[A]

Я ожидал, что компилятор выполнит вывод типа для типа A, но после того, как попробовал следующее:

new C[A[Int]]

Iполучено следующее сообщение об ошибке:

(fragment of Main.scala):11: error: this.A[Int] takes no type parameters, expected: one
println( new C[A[Int]] )

Ответы [ 5 ]

15 голосов
/ 06 января 2011

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

class A[X]

означает: пусть A будет классом, который принимает один параметр типа.

class C[M[X] <: A[X]]

означает: пусть C будет классомкоторый принимает один параметр типа, который должен быть классом, который принимает один параметр типа И, параметризованный, является подклассом класса А, параметризованного с тем же типом.

Когда вы пишете

new C[A]

Вы говорите: создайте экземпляр C с параметром A.Соответствует ли A критериям, указанным выше?Да, это класс, который принимает один параметр типа, а параметризованный это подкласс самого параметризованного.

Однако, когда вы пишете

new C[A[Int]]

параметр типа, который вы пытаетесь датьC, [Int], не соответствует критериям: A [Int] не принимает никаких типов параметров, которые любезно сообщит вам компилятор.(И это также не подкласс A [X].)

6 голосов
/ 06 января 2011

Попробуйте этот синтаксис.

class C[M <: A[_]]

Это означает, что C является классом, который принимает один параметр типа, который должен быть подклассом A и принимает один параметр типа.

2 голосов
/ 06 января 2011

Вы не объявили X в качестве параметра типа для C.Попробуйте следующее:

class C[X, M[X] <: A[X]]
1 голос
/ 11 декабря 2014

Это все объяснено здесь , сосредоточьтесь на разделе "Common Pitfalls", потому что это довольно TLTR.

0 голосов
/ 20 февраля 2011

Вы не хотите, чтобы ваш класс принимал ОДИН параметр типа, вы не хотите принимать два! Два возможных решения:

class A[X] {
     type T = X
}
class C[M <: A[_]] {
     //use M#T if you want the type T was parameterized with.
}

Или вы можете сделать:

class A[X]
class C[T, M[A] <: A[A]] {
     //when you want the type, write M[T], not M.
}

ОДНАКО, что вы, вероятно, хотите, это:

class A[X]
class C[M <: A[_]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...