Понимание «аргументов типа не соответствуют границам параметров типа» в Scala - PullRequest
6 голосов
/ 27 июля 2011

Почему не работают следующие функции?

scala> abstract class Foo[B<:Foo[B]]
defined class Foo

scala> class Goo[B<:Foo[B]](x: B)
defined class Goo

scala> trait Hoo[B<:Foo[B]] { self: B => new Goo(self) }
<console>:9: error: inferred type arguments [Hoo[B] with B] do not conform to class Goo's type parameter bounds [B <: Foo[B]]
       trait Hoo[B<:Foo[B]] { self: B => new Goo(self) }
                                         ^

scala> trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) }
<console>:9: error: inferred type arguments [Hoo[B]] do not conform to class Goo's type parameter bounds [B <: Foo[B]]
       trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) }
                                             ^

В первой попытке, не Hoo[B] with B <: Foo[B]?

Во второй попытке, не Hoo[B] <: Foo[B]?

Чтобы мотивировать эту проблему, есть библиотека с:

// "Foo"
abstract class Record[PK, R <: Record[PK, R]] extends Equals { this: R =>
  implicit def view(x: String) = new DefinitionHelper(x, this)
  ...
}
// "Hoo"
class DefinitionHelper[R <: Record[_, R]](name: String, record: R) {
  def TEXT = ...
  ...
}

// now you can write:
class MyRecord extends Record[Int, MyRecord] {
  val myfield = "myfield".TEXT
}

Я пытаюсь ввести новый метод расширения наряду с TEXT, который называется BYTEA, чтобы можно было написать:

class MyRecord extends XRecord[Int, MyRecord] {
  val myfield = "myfield".BYTEA // implicit active only inside this scope
}

Мои попытки:

class XDefinitionHelper[R <: Record[_, R]](name: String, record: R) {
  def BYTEA = ...
}

trait XRecord[PK, R <: Record[PK, R]] { self: R =>
  implicit def newView(x: String) = new XDefinitionHelper(x, self)
}

Но это сталкивается с теми же проблемами, что и мой маленький тестовый пример выше.

Ответы [ 2 ]

2 голосов
/ 27 июля 2011

В первой попытке у вас есть Hoo[B] with B <: Foo[B]. Но для существования Goo[Hoo[B] with B] необходимо Hoo[B] with B <: Foo[Hoo[B] with B]. Аналогично во втором случае.

0 голосов
/ 21 августа 2013

Это кажется слишком простым, чтобы быть правдой (т.е., чтобы быть хорошей практикой), но это все равно спасло мой день, поэтому, где оно находится:

scala> trait MyTrait[T <: MyTrait[T]] { self: T => def hello = println("hello") }

scala> case class User(t: MyTrait[_])
<console>:8: error: type arguments [_$1] do not conform to trait MyTrait's type parameter bounds [T <: MyTrait[T]]
       case class User(t: MyTrait[_])

scala> case class User(t: () => MyTrait[_])
defined class User
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...