Evgeny Veretennikov
Evgeny Veretennikov

Reputation: 4229

Scala: pass implicit argument to function which returns another function

Let's say, I have four classes

class I
class A
class B
class C

And function which takes two arguments, one of which is implicit, and returns another function:

def f(arg: String)(implicit i: I): (C => B) => A = _ => new A

I have implicit I somewhere in scope:

implicit val i = new I

So, I want to invoke f this way:

f("123") { c => new B }

But I can't because of missing parameter type error on lambda param c. Ok, let's add this parameter explicitly:

f("123") { c: C => new B }

Then I have type mismatch: second f parameter needs to be I, but instead is C => B!

I see now two options, how to solve this. First is to simply pass parameter explicitly:

f("123")(i) { c => new B }

But we don't always have access to implicit values. Also, we can divide function invocation into two expressions:

val g = f("123")
g { c => new B }

This gives what we need, but code seems cumbersome. I'd like to invoke function simpler.

So, how to invoke such function in one line?

Upvotes: 2

Views: 791

Answers (3)

Jasper-M
Jasper-M

Reputation: 15086

Another option is explicitly writing apply.

f("123") apply { c => new B }
f("123").apply( c => new B )

Upvotes: 3

tharindu_DG
tharindu_DG

Reputation: 9261

I think Implicitly is a fit for your use case.

f("123")(implicitly[I])((c: C) => new B)

Implicitly is available in Scala 2.8 and is defined in Predef as:

def implicitly[T](implicit e: T): T = e

Hope this helps.

Upvotes: 4

Evgeny Veretennikov
Evgeny Veretennikov

Reputation: 4229

We can write simple wrapper for such function f:

def g(arg: String)(fun: C => B)(implicit i: I) => A = f(arg)(i)(fun)

Now implicit parameter is really last function parameter and we are able to invoke g this way in one line:

g("123") { c => new B }

Upvotes: 0

Related Questions