9
def multi_fun(i:Int, s:String)(d:Double) […]

How to pass this function now to another function as an argument, i.e. which parameter type needs to be indicated?

def fun_that_likes_multi_fun(mf:(Int, String)(Double) ⇒ Unit) […]

This would not work, fails even to parse.

Majakovskij
  • 565
  • 4
  • 10

2 Answers2

10
def fun_that_likes_multi_fun(mf:(Int, String)=>Double => Unit)={}

The function you have mentioned is a curried function. Which means the result of applying the first argument list is another function that takes the second argument list to process in entirety. So it is represented as such.

Som Bhattacharyya
  • 3,972
  • 35
  • 54
  • Thank you for your answer! How would I pass a function with implicit parameters though, i.e. def multi_fun(i:Int, s:String)(implicit d:Double) […] The compiler says: "could not find implicit value for parameter d", i.e. it thinks that I like to apply the multi_fun instead of passing it as an argument. How can I tell Scala to do that? “multi_fun _" does not work either. – Majakovskij Apr 06 '16 at 08:00
  • You would do it the same way. Just make sure that a double value is available implicitly at that point. Like `implicit val d:Double = 1.00` – Som Bhattacharyya Apr 06 '16 at 09:21
  • It doesn't seem to work like that: def multi_fun(i: Int, s: String)(implicit d: Double) {} def fun_that_likes_multi_fun(mf: (Int, String) => Double => Unit) { /*implicit*/ val d1:Double = 1.0 mf(1, "a")(d1) } /*implicit val d2:Double = 1.0*/ fun_that_likes_multi_fun(multi_fun) Even if d2 was available, it does not compile (which is not what I want anyway but the actual use case is shown by d1: the multi_function is usually used with an implicit value but for this particular case needs to be passed to a higher-order function). – Majakovskij Apr 06 '16 at 10:19
  • see here : http://stackoverflow.com/questions/10881340/scala-currying-on-multi-parameter-group-method-including-implicit-params – Som Bhattacharyya Apr 06 '16 at 10:42
8

Just like this:

def multiFun(i:Int, s:String)(d:Double):Unit  = ???

def highOrderFun(mF:(Int, String) => Double => Unit) = ???

highOrderFun(multiFun)

Think of multiFun as of function that takes (Int, String) and returns function with type Double => Unit.

Upd: Regarding implicit parameters. It seems that it's not possible to pass a method with implicit parameters as is. See some details here. Although I can see nice workaround for your case:

def multiFun(i:Int, s:String)(implicit d:Double):Unit  = ???

def highOrderFun(mF:(Int, String, Double) => Unit) = ???

highOrderFun(multiFun(_, _)(_))

This syntax multiFun(_, _)(_) just creates wrapper function around multiFun that takes three parameters whose types are inferred from params of multiFun.


UPD: In response to @ackratos:

It appears that there is no way to make lambda function type generic. Mainly because there is a fundamental difference between lambda functions and methods.

But as functions above are defined as methods, nothing prevents us from making them generic:

def multiFun[T](i:T, s:String):Unit  = ???

def highOrderFun[T](mF:(T, String) => Unit) = ???

highOrderFun(multiFun[Int])

 

It's possible to reference function that has implicit param list as function without one. In this case missing implicit params will be substituted by resolved values:

def multiFun(s:String)(implicit i:Int):Unit  = ???

def highOrderFun(context:Any)(mF:String => Unit)(implicit i:Int) = ???

implicit val param = 2
highOrderFun(1.0)(multiFun)  // param i:Int is resolved here
Community
  • 1
  • 1
Aivean
  • 10,692
  • 25
  • 39
  • Thank you for your answer! How would I pass a function with implicit parameters though, i.e. def multi_fun(i:Int, s:String)(implicit d:Double) […] The compiler says: "could not find implicit value for parameter d", i.e. it thinks that I like to apply the multi_fun instead of passing it as an argument. How can I tell Scala to do that? “multi_fun _" does not work either. – Majakovskij Apr 06 '16 at 07:57
  • Thank you for your answer and the workaround! This is exactly the one that I was using, too, I just didn't find it “nice”. ;-) I think in a very streamlined language like Scala seems to me there should be an immediate way to pass functions with implicit parameters. – Majakovskij Apr 25 '16 at 15:01
  • what if multiFun and highOrderFun take type parameter? – ackratos Feb 27 '17 at 14:08
  • @Aivean thank you very much for your update. It's my fault not specified my problem clear. Actually, my highOrderFun takes two parameter list, (content: T)(mf: (T: String) => Unit multiFun still take implicit parameter what I want achieve is call highOrderFun(1.0)(multiFun) without specify type parameter of multiFun – ackratos Feb 28 '17 at 13:53