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).
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.
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.
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!"
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.
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.
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