Как можно использовать последствия с несколькими входами в Scala? - PullRequest
11 голосов
/ 10 марта 2010

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

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

val s: String = ... //?

Спасибо

Ответы [ 2 ]

18 голосов
/ 10 марта 2010

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

Вы можете применить неявное представление к 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]
4 голосов
/ 15 мая 2011

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

Вот пример неявного преобразования, которое принимает два аргумента,

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
...