barbara
barbara

Reputation: 3201

Scala: How to define anonymous function with implicit parameter?

I want to define a function with implicit parameter in a way like this:

// imports to add scope of A

{
  implicit a: A => {
    // some action
  }
}.apply()

// somewhere in the code           

class A

val a: A = new A

But my Scala compiler doesn't compile it. It says: Cannot resolve reference apply with such signature. However, the parameter is implicit, so I guess compiler should look up in the scope and find an appropriate object.

Is it true? If not, then how can I fix it?

Upvotes: 5

Views: 5133

Answers (2)

Giovanni Caporaletti
Giovanni Caporaletti

Reputation: 5556

You can't. Only methods can have implicit parameters.

When you do this:

// val f: A => Unit = 
{
   implicit a: A => {
     // some action
   }
}

you're actually declaring an anonymous function of type A => Unit and you are declaring the argument a as implicit in the function body


You can achieve something close to what you want using the magnet pattern:

class A

case class Magnet()
object Magnet {
  implicit def fromUnit(arg1: Unit)(implicit a: A) = Magnet()
}

object Test extends App {

  implicit val a = new A

  {
    args: Magnet => {
      //...
    }
  }.apply()
}

You'll get a deprecation warning though because the magnet must have at least one parameter and I used Unit, you should call it like .apply(()) to avoid it

Upvotes: 8

alextsc
alextsc

Reputation: 1368

As said by Giovanni: You can't have such a parameter.

However you can use implicitly to resolve implicits within your function:

case class Foo(text : String)
implicit val foo = Foo("World")

(() => {
  val implFoo : Foo = implicitly[Foo]
  println(s"Hello ${implFoo.text}")
}).apply()

(But to be honest this sounds like it can be written better and you're going into spaghetti code territory with what you're doing.)

Upvotes: 3

Related Questions