Is it possible to do something like the following?
def takeCurriedFnAsArg(f: (Int)(implicit MyClass) => Result)
Scala - Functions with Named Arguments Named arguments allow you to pass arguments to a function in a different order. The syntax is simply that each argument is preceded by a parameter name and an equals sign. Try the following program, it is a simple example to show the functions with named arguments.
Currying is the process of converting a function with multiple arguments into a sequence of functions that take one argument. Each function returns another function that consumes the following argument.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
Advantages of Currying Function in Scala One benefit is that Scala currying makes creating anonymous functions easier. Scala Currying also makes it easier to pass around a function as a first-class object. You can keep applying parameters when you find them.
Yes, it is possible.
When you have the second curried parameter marked as implicit
, the function seems to be not of type
Int => (MyClass => Result) => ResultOfFunction
which it would be if the curried higher order function parameter was a regular parameter; instead, it looks like this:
Int => ResultOfFunction
Here's a quick example:
scala> def curriedFn(i : Int)(implicit func : String => Int) : Boolean = (i + func("test!")) % 2 == 0
curriedFn: (i: Int)(implicit func: String => Int)Boolean
scala> implicit val fn : String => Int = s => s.length
fn: String => Int = <function1>
scala> curriedFn _
res4: Int => Boolean = <function1>
As you can see, the implicit
parameter got 'eliminated'. Why and how? That's a question for someone more knowledgeable than me. If I had to guess, I'd say the compiler directly substitutes the parameter with the implicit value, but that might very well be false.
Anyway, digressions aside, here's an example very relevant to your situation:
scala> def foo(func : Int => Boolean) = if(func(3)) "True!" else "False!"
foo: (func: Int => Boolean)String
scala> foo(curriedFn)
res2: String = True!
Now if the second function parameter wasn't implicit:
scala> def curriedNonImplicit(i : Int)(fn : String => Int) : Boolean = (i + fn("test!")) % 2 == 0
curriedNonImplicit: (i: Int)(fn: String => Int)Boolean
scala> curriedNonImplicit _
res5: Int => ((String => Int) => Boolean) = <function1>
As you can see, the type of the function is a bit different. That means that the solution will look different too:
scala> def baz(func : Int => (String => Int) => Boolean) = if(func(3)(s => s.length)) "True!" else "False!"
baz: (func: Int => ((String => Int) => Boolean))String
scala> baz(curriedNonImplicit)
res6: String = True!
You have to specify the function directly inside the method, as it wasn't implicitly provided before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With