Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a function with implicit as parameter

I want to pass a function fun1 as a parameter to fun2. However fun1 needs an implicit parameter. Is is possible to define that implicit value inside fun2?

The code is like this:

import org.json4s._
import org.json4s.jackson.JsonMethods._

  def fun1(json:JValue)(implicit formats: Formats) = {

        //do something
  }


  def fun2(f: (JValue) => RatEvent,line:String ) = {

        implicit val formats = DefaultFormats  //has been defined in import
        val json = parse(line)  //covert string to jvalue
        val result = f(json)
  }

Here I pass fun1 to fun2, compiler complains that it cannot find implicit value for fun1.

  fun2(fun1,"asdfasdf")    //error here,   fun1 is lack of an implicit value

I want to solve the problem by changing the shape of fun2 i.e.

def fun2(f: (JValue)(implicit Formats) => RatEvent,line:String ) //doesn't compile

But I don't know how to write it correctly.

Supplement:

Declare an implicit Format may seems a good solution. But I have to define it in fun2. I have made problem simple. The real funs looks like:

  def fun2(f: (JValue) => RatEvent,lines:RDD[String] )(implicit sc:SparkContext) = {

        for (
          line <- lines
        ){
        implicit val formats = DefaultFormats  //has been defined in import
        val json = parse(line)  //covert string to jvalue
        val result = f(json)
        ......
        }
  }

formats has to be defined inside of lines's map function (I used for instead).

like image 948
worldterminator Avatar asked Apr 24 '15 02:04

worldterminator


People also ask

How do you pass a parameter as an implicit parameter?

It's passed by specifying the reference or variable of the object before the name of the method.  An implicit parameter is opposite to an explicit parameter, which is passed when specifying the parameter in the parenthesis of a method call. If a parameter isn't explicitly defined, the parameter is considered implicit.

What are implicit parameters in Scala?

Implicit parameters are the parameters that are passed to a function with implicit keyword in Scala, which means the values will be taken from the context in which they are called. In simpler terms, if no value or parameter is passed to a method or function, then the compiler will look for implicit value and pass it further as the parameter.

What is an implicit keyword in Python?

When implicit keyword used in the parameter scope of the function, all the parameters are marked as implicit. Note: A method can only contain one implicit keyword. implicit val name = "world!"

Are arguments passed by value or parameter?

Arguments are Passed by Value. The parameters, in a function call, are the function's arguments. JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations.


1 Answers

A Scala function value's apply method only has one parameter list and does not take any implicit parameters. You can't do anything about that.

You could change the shape of fun2 to take the extra parameter as a normal parameter:

class J; class F; class R

def fun1(j: J)(implicit f: F): R =
  new R
def fun2(fn: (J, F) => R) {
  fn(new J, new F)
}

fun2(fun1(_)(_))

But yuck; the call site isn't as nice as the fun2(fun1) you wanted.

If you have an implicit F in scope at the call site, then you can change the shape of fun2 as follows:

class J; class F; class R

def fun1(j: J)(implicit f: F): R =
  new R

def fun2(fn: J => R)(implicit f: F) {
  fn(new J)
}

implicit val f = new F
fun2(fun1)

Yay, clean call site!

Does this meet your requirements? In your question, you only have a Formats in implicit scope inside the body of fun2, but I can't tell if that's a necessary condition of your question, or just something accidental about the way you condensed your code to fit in a question.

like image 197
Seth Tisue Avatar answered Nov 07 '22 05:11

Seth Tisue