Будет ли поддержка Scala обнаруживать неявный параметр из вызывающей стороны, а не из определения? - PullRequest
0 голосов
/ 28 июня 2018

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

package tagedfuture

class Future[+T](f: => T)(implicit tag: String) {

  def map[B](f2: T => B): Future[B] = {
    Future(f2(f))
  }

  def flatMap[B](f2: T => Future[B]): Future[B] = {
    f2(f)
  }

  def getTag = tag
}

object Future {
  def apply[T](f: => T)(implicit tag: String): Future[T] = new Future(f)

}

object Test extends App {
  val fur = Future{
    10
  }("future-chain-1")

  val fur2 = fur.map(x => x * 2)

  val fur3 = fur2.flatMap(x => {
    anotherFuture(x)(fur2.getTag)
    // expect this:
    // anotherFuture(x)
  })

  def anotherFuture(int: Int)(implicit tag: String): Future[String] = {
    Future(int.toString)
  }

  // expect this:
  //def anotherFuture(int: Int): Future[String] = {
  //  Future(int.toString)
  //}

  assert(fur.getTag == fur2.getTag && fur2.getTag == fur3.getTag)
}

tagedfuture.Future.apply ожидаем, что неявный параметр используется для обозначения источника экземпляра Future.
В методе anotherFuture он может выполняться, который имеет параметр implicit tag: String для передачи тега при создании нового Future.

Мы должны добавить неявный параметр для anotherFuture, потому что компилятор определяет контекст метода, который из import package, определения класса, помещается. но не проверять его вызывающим абонентом.

как насчет поддержки обнаружения неявных от вызывающей стороны?
Мы можем использовать //expect this:, который удаляет весь неявный шаблонный код. Даже если мы удалили его, мы можем получить неявный экземпляр от вызывающей стороны, в котором сначала Future fur1's "future-chain-1".

Кажется, сложнее, чем нынешний орудие. Будет ли Scala поддерживать этот способ использования неявного?

UPDATE

Что именно означает обнаружение вызывающей стороной с точки зрения рабочего процесса компилятора?

В настоящее время, когда мы определили метод, который использует метод, имеет неявный параметр, такой как def anotherFuture, компилятор проверит контекст метода, который содержит import pacakge, неявная переменная в определении относительного класса / объекта и сообщение об ошибке, если не существует неявной переменной, соответствующей методу.
Параметр «обнаружение вызывающей стороной» означает, что компилятор не проверяет место места определения метода, а проверяет место вызывающей стороны, где вызывается метод. На данном этапе место звонка - anotherFuture(x)(fur2.getTag). Контекст содержит Test объект, fur2 экземпляр и flatmap метод.
Я ожидаю, что он будет скомпилирован путем обнаружения экземпляра fur2, где есть переменная tag.

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

1 Ответ

0 голосов
/ 28 июня 2018

Напомним, что вы хотите, чтобы компилятор проверял каждую переменную в области видимости (в месте, где вызывается метод с неявным параметром), ища любой (открытый) член своего класса, который сам помечен как неявный и соответствующий ожидаемому типу, чтобы предоставить его вызываемому методу в качестве аргумента неявного параметра.

Я думаю, что это было бы весьма неоднозначно (что вы подразумеваете, если у вас есть два экземпляра Future[X] в области действия?), Значительно замедлило бы компилятор и просто не было бы управляемым для человеческого мозга.

Итак, мой ответ - нет. (если я правильно понял ваш вопрос)

...