Подтвердить что ты не робот

Как использовать в Scala имплициты с несколькими входами?

Например, как я могу написать выражение, в котором неявно применяется следующее:

implicit def intsToString(x: Int, y: Int) = "test"

val s: String = ... //?

Спасибо

4b9b3361

Ответ 1

Неявные функции одного аргумента используются для автоматического преобразования значений в ожидаемый тип. Они известны как "Неявные представления". С двумя аргументами это не работает или имеет смысл.

Вы можете применить неявный вид к TupleN:

implicit def intsToString( xy: (Int, Int)) = "test"
val s: String = (1, 2)

Вы также можете пометить конечный список параметров любой функции как неявный.

def intsToString(implicit x: Int, y: Int) = "test"
implicit val i = 0
val s: String = intsToString

Или, комбинируя эти два использования implicit:

implicit def intsToString(implicit x: Int, y: Int) = "test"
implicit val i = 0
val s: String = implicitly[String]

Однако это не очень полезно в этом случае.

UPDATE

Чтобы уточнить комментарий Мартина, это возможно.

implicit def foo(a: Int, b: Int) = 0
// ETA expansion results in:
// implicit val fooFunction: (Int, Int) => Int = (a, b) => foo(a, b)

implicitly[(Int, Int) => Int]

Ответ 2

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

Здесь пример неявного преобразования, который принимает два аргумента,

case class Foo(s : String)
case class Bar(i : Int)

implicit val defaultBar = Bar(23)

implicit def fooIsInt(f : Foo)(implicit b : Bar) = f.s.length+b.i

Пример сеанса REPL,

scala> case class Foo(s : String)
defined class Foo

scala> case class Bar(i : Int)
defined class Bar

scala> implicit val defaultBar = Bar(23)
defaultBar: Bar = Bar(23)

scala> implicit def fooIsInt(f : Foo)(implicit b : Bar) = f.s.length+b.i
fooIsInt: (f: Foo)(implicit b: Bar)Int

scala> val i : Int = Foo("wibble")
i: Int = 29