Может ли аргумент метода служить неявным параметром для неявного преобразования? - PullRequest
1 голос
/ 04 сентября 2011

Следующий код в сеансе REPL:

case class Foo(x : Int)

case class Bar(x : Int)

case class Converter(y : Int) {
    def convert(x : Int) = x + y
}

implicit def fooFromBar(b : Bar)(implicit c : Converter) = Foo(c convert (b x))

def roundaboutFoo(x : Int, converter : Converter) : Foo = Bar(x)

Дает мне эту ошибку:

ошибка: не удалось найти неявное значение для параметра c: конвертер def roundaboutFoo (x: Int, конвертер: Converter): Foo = Бар (х)

В случае, если это не очевидно (подразумевается), я пытаюсь сделать Bar(x) неявно преобразованным в Foo. Само неявное преобразование параметрируется неявным Converter. Для всех случаев, когда я хочу использовать это преобразование, в качестве параметра метода доступен экземпляр Converter.

Я почти ожидал, что это умрет, так как не смог найти неявное преобразование из Bar в Foo, из-за того, что fooFromBar не является простой функцией от Foo до Bar, но я прочитал в этом вопросе , что неявные преобразования могут иметь неявные параметры, и, действительно, компилятор, похоже, понял эту часть.

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

Мне было интересно, что происходило в том, что Scala не смотрит на аргументы локального метода при проверке локальной области видимости для значений, передаваемых как неявные параметры. Но добавление что-то вроде val c = converter к roundaboutFoo не меняет получаемого сообщения об ошибке.

Можно ли заставить это работать? Если нет, может ли кто-нибудь помочь мне понять, на что обратить внимание, чтобы распознать, что такой код не будет работать?

1 Ответ

6 голосов
/ 04 сентября 2011

converter должен быть либо самим неявным параметром:

def roundaboutFoo(x: Int)(implicit converter: Converter): Foo = Bar(x)

, либо назначенным неявному значению:

def roundaboutFoo(x: Int, converter: Converter): Foo = {
  implicit val conv = converter
  Bar(x)
}

Обычные параметры не являются неявными и, следовательно, не являются 'поиск при попытке ввести неявный аргумент.

...