2016-02-13 4 views
0

Я пытаюсь написать код для преобразования неявного аргумента, как следующее:Scala неявного преобразования неявного аргумента

case class A() 
case class B() 
object B { 
    implicit def b2a(b: B): A = new A() 
} 

def foo(f: B => String) = f(new B()) 
def bar(implicit a: A) = "A" 

foo { implicit b => 
    bar() 
} 

выдает ошибку:

<console>:27: error: not enough arguments for method bar: (implicit a: A)String. 
Unspecified value parameter a. 

Есть ли способ использовать неявное преобразование, не вызывая его вручную?

+1

Это не ответ, но вы абсолютно уверены, что вам нужно это сделать? Вы уже видели, какой путаный беспорядок - это нужно рассуждать о том, как эти импликации будут решены. Вы действительно хотите навязать эту путаницу всем, кто когда-либо использовал ваш код? –

+0

Согласен. Это больше проблем, чем для этого, но я принял ответ @ m-z, потому что он исправил проблему. – pschorf

ответ

2

Я считаю, что это нарушает правило «один за раз». В рамках вашего звонка bar не подразумевается A, только неявный B. Если компилятор попытался также неявно преобразовать неявный B в A, это будет два шага, а не один.

Однако вы можете обойти это через неявное сцепление.

implicit def a(implicit b: B): A = new A() 

Если этот метод находится в области видимости, компилятор будет видеть в рамках неявного A, до тех пор, как он может заполнить неявную B, что он может.

scala> foo { implicit b => bar } 
res1: String = A 

Конкретная ошибка, с которой вы столкнулись, заключалась в том, что вам нужно было удалить скобки, которые я здесь сделал. Это приводит к ошибке «неявной не найденной», описанной выше.

+0

И можно сделать это всегда в области видимости, помещая его в объект-компаньон 'A' вместо' B'. – Kolmar

+0

'' по одному правилу' - не могли бы вы предоставить ссылку, m-z? –

+0

@KevinMeredith [Программирование в Scala 21.2 by Odersky, Spoon и Venners] (https://www.artima.com/pins1ed/implicit-conversions-and-parameters.html#21.2) –