11

For example, how can I write an expression where the following is implicitly applied:

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

val s: String = ... //?

Thanks

Dimitris Andreou
  • 8,806
  • 2
  • 33
  • 36

2 Answers2

18

Implicit functions of one argument are used to automatically convert values to an expected type. These are known as Implicit Views. With two arguments, it doesn't work or make sense.

You could apply an implicit view to a TupleN:

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

You can also mark the final parameter list of any function as implicit.

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

Or, combining these two usages of implicit:

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

However it's not really useful in this case.

UPDATE

To elaborate on Martin's comment, this is possible.

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]
retronym
  • 54,768
  • 12
  • 155
  • 168
  • Do you imply ( :-) ) that my original def (which doesn't have implicit parameter list) cannot be invoked implicitly? (That would mean that the "implicit" keyword is completely meaningless in my example - if no code could ever observe a difference). Is that really the case? Or is this intended as a partial answer, in the sense of "hey, at least these cases work"? – Dimitris Andreou Mar 10 '10 at 15:20
  • 1
    Correct. I know of know way in the current language that this could be invoked. A compiler warning could be helpful to communicate this fact. – retronym Mar 10 '10 at 15:51
  • 8
    The original function cannot be used as an implicit conversion, because it takes two parameters. However, it can still be used as an implicit argument for another method. So the `implicit' modifier does have a useful meaning here. – Martin Odersky Mar 10 '10 at 16:44
  • 1
    Wow. Thanks Martin, I got a warm feeling now, experiencing the orthogonality of constructs at work - indeed, all functions are values, so what you say can only make sense. Implicit defs are also implicit values. Nice. – Dimitris Andreou Mar 10 '10 at 18:19
  • "Implicit defs are also implicit values." I'm going to tweet that. :-) – Daniel C. Sobral Mar 10 '10 at 20:32
  • So everytime you declare an implicit conversion, you also declare an implicit value. Does this make sense? – ziggystar May 15 '11 at 20:31
4

Jason's answer misses out one very important case: an implicit function with multiple arguments where all but the first are implicit ... this requires two parameter lists, but that doesn't seem to be out of scope given the way the question was expressed.

Here's an example of an implicit conversion which takes two arguments,

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

Sample REPL session,

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
Miles Sabin
  • 23,015
  • 6
  • 61
  • 95