Определение метода, тип возвращаемого значения которого является одноэлементным типом аргумента этого метода - PullRequest
2 голосов
/ 07 апреля 2011

Все еще борется с this.types (синглтон-типами). Предположим этот сценарий:

trait Sys[A <: Access] {
  def in[T](v: String): AccessPrepare[A]
}

trait AccessPrepare[A <: Access] {
  val a: A
  def apply[T](fun: a.type => T): T
}

object Ref {
  def single[A <: Access, V](v: V)(implicit a: A): Ref[A, V] = ???
}
trait Ref[A, V]

trait Access {
  def set(r: Ref[this.type, Int]): Unit
}

Следующие ошибки:

def test(sys: Sys[Access]): Unit =
  sys.in("v1") { implicit a =>
    val r = Ref.single(44)
    a.set(r)
  }

потому что, очевидно, r имеет тип Ref[Access, Int], а не Ref[a.type, Int]. Я думаю, проблема в том, что мне нужна строка вроде

def single[A <: Access, V](v: V)(implicit a: A): Ref[a.type, V] = ...

, который не компилируется из-за «недопустимого типа зависимого метода» ...

Любые идеи, как я могу это исправить. Требование заключается в том, что я не аннотирую вызовы явно. То есть я не хочу написать Ref.single[a.type, Int](44)(a) по понятным причинам.


EDIT

В качестве пояснения со ссылкой на ответ «К вашему сведению и закрыть вопрос» в потоке Ограничение операции путем сопоставления параметра типа с типом аргумента, зависящим от пути - что я хотел бы Кроме того, есть возможность создавать объекты (Refs) не с помощью фабричного метода в Access, а где-то снаружи (например, с помощью оператора new). Поскольку система не может быть ограничена определением Access, я должен иметь возможность расширять ее другими объектами.

1 Ответ

1 голос
/ 09 апреля 2011

У вас есть несколько возможностей. В Scala 2.8 / 2.8.1 вы можете использовать приватную опцию -Ydependent-method-types, а затем свое решение с

def single[ A <: Access, V ]( v: V )( implicit a: A ) : Ref[ a.type, V ] = // ...

отлично компилируется.

Если вы хотите избежать зависимых типов методов, потому что это частная опция, вы все равно можете скомпилировать свое первое предложение, явно набрав вызов Ref.single:

  val r = Ref.single[a.type, Int](44)

Однако вам необходимо указать тип, поскольку одноэлементные типы никогда не выводятся. Ваша проблема не такая же, как и проблема, связанная с тем, что одноэлементные типы не выводятся: см. Как правильно аннотировать этот список HList?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...