Scala Functional Literals with Implicits

scala>  val sum2 = (a: Int) => {implicit b: Int => a + b}
sum2: (Int) => (Int) => Int = <function1>

This will just make b an implicit value for the scope of the function body, so you can call methods that expect an implicit Int.

I don't think you can have implicit arguments for functions since then it is unclear what the function is. Is it Int => Int or () => Int?

The closest I found is:

scala> case class Foo(implicit b: Int) extends (Int => Int) {def apply(a: Int) = a + b}
defined class Foo

scala> implicit val b = 3
b: Int = 3

scala> Foo()
res22: Foo = <function1>

scala> res22(2)
res23: Int = 5

In this snippet

scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>

Note that the precise type of sum2 is Function1[Int, Function1[Int, Int]]. It could also be written as

val sum2 = new Function1[Int, Function1[Int, Int]] {
    def apply(a: Int) = new Function1[Int, Int] {
        def apply(b: Int) = a + b
    }
}

Now, if you try to make b implicit, you get this:

scala>     val sum2 = new Function1[Int, Function1[Int, Int]] {
     |         def apply(a: Int) = new Function1[Int, Int] {
     |             def apply(implicit b: Int) = a + b
     |         }
     |     }
<console>:8: error: object creation impossible, since method apply in trait Function1 of type (v1: Int)Int is not defined
               def apply(a: Int) = new Function1[Int, Int] {
                                       ^

Or, in other words, Function's interfaces do not have implicit parameters, so anything with an implicit parameter is not a Function.


Try overloading the apply method.

scala> val sum = new Function1[Int, Function1[Int, Int]] {
         |      def apply(a: Int) = (b: Int) => a + b
         |      def apply(a: Int)(implicit b: Int) = a + b
         |}
sum: java.lang.Object with (Int) => (Int) => Int{def apply(a:Int)(implicit b: Int): Int} = <function1>

scala> sum(2)(3)
res0: Int = 5

scala> implicit val b = 10
b: Int = 10

scala> sum(2)
res1: Int = 12