2012-10-12 3 views
2

Я пытаюсь создать оболочку карты в Scala 2.9.2 со значениями, имеющими определенный более высокий тип сорта, и борюсь с системой типов. Вот урезанная версия кода, чтобы проиллюстрировать эту проблему:Ограничения типа соответствия в Scala не удались

trait A 

trait B[C] { 
    def c: C 
} 

trait E[C <: B[C], D <: A] 

case class MyMap[M <: A, L <: B[L], N[L, M]](map: Map[M, N[L, M]]) 

object MyMap { 
    def empty[M <: A, L <: B[L], N[L, M]] = MyMap(Map.empty[M, N[L, M]]) 
} 

val myMap = MyMap.empty[A, T forSome { type T <: B[T] }, E] 

, когда я пытаюсь скомпилировать это, последнее утверждение терпит неудачу с ошибкой компилятора, указывая, что я не соответствующие оценки типа. Однако мне кажется, что я, и, возможно, где у меня есть N [L, M] и ранее L <: B [L], не следует, что L в N [L, M] является тем же L < : B [L], и также для M. Error выглядит следующим образом:

виды аргументов типа (а, Т forSome {тип Т <: в [Т]}, Е) не соответствуют к ожидаемые виды параметров типа (тип M, тип L, тип N). Параметры типа E не соответствуют ожидаемым параметрам типа N: ограничения типа C>: Ничто <: B [C] более строгие, чем объявленные границы типа L>: Ничто <: Любые, тип D '>: ничего <: A более строгие, чем тип М объявленных границы>: Ничего <: Любые

вал MyMap = MyMap.empty [А, Т forSome {тип Т <: В [Т]}, Е]

Любые советы благодарностью.

Спасибо -

ответ

2

Там находится одна проблема со вторым параметром и один с третьим. Я не знаю о втором параметре, я не уверен, что может быть разрешено здесь с existentia. Так что это проблема с третьим параметром.

Немного более простого код с той же ошибкой:

class A {} 

class C[X <: A] {} 

def f[X[_]] = 12 

f[List] 
res1: Int12 
f[C] 
error: kinds of the type arguments (C) do not conform to 
the expected kinds of the type parameters (type X). 
C's type parameters do not match type X's expected parameters: 
    type X's bounds >: Nothing <: A are stricter 
    than type _'s declared bounds >: Nothing < : Any 
     f[C] 
     ^

Проще говоря, метод пустой ожидает в качестве параметра третьего типа общего типа с двумя параметрами и без каких-либо ограничений. В теле пустого вам разрешено писать N[Int, String] или что угодно. Тип E, который имеет некоторые ограничения, несовместим с этим (примечание: я нахожу writing N[L,M], а не N[_, _], с L и M имя предыдущего типа параметров немного вводит в заблуждение. Или, может быть, это предполагает, что вы действительно не хотите, чтобы параметр более высокого порядка).

Если вы пишете в коде выше

def g[X[_ <: A]] = 13 

g[C] то вызов нормально (g[List] слишком хорошо, как и положено, ничего плохого не может случиться там).

Точно так же, ваш код будет работать (если вы пройти соответствующий второй параметр), если пусто было

Map.empty[M <: A, L <: B[L], N[X <: B[X], Y <: A]] 
+0

спасибо за быстрый ответ. Используя ваш пример и мой признак B, если C был определен как 'class C [X <: B [X]] {}', как бы вы тогда определили функцию g? – fhusb

+0

def g [X [Y <: B [Y]] (так же, как пустой на последней строке, N [X <: B [X] ...]) –

+0

спасибо. Так что, если бы я хотел сказать список этих Cs, без каких-либо ограничений, чем на C (я думаю, что это настоящая проблема, которую я когда-то снимал).Я пробовал 'val l = List [C [T forSome {type T <: B [T]}]()', который жалуется на «аргументы типа [T forSome {type T <: B [T]}] не соответствуют ограничениям параметра типа C [X <: B [X]] " – fhusb

Смежные вопросы