Accessing a Class Member from a First-Class Function
I have a case class which takes a list of functions:
case class A(q:Double, r:Double, s:Double, l:List[(Double)=>Double])
I have over 20 functions defined. Some of these functions have their own parameters, and some of them also use the q
, r
, and s
values from the case class. Two examples are:
def f1(w:Double) = (d:Double) => math.sin(d) * w
def f2(w:Double, q:Double) = (d:Double) => d * q * w
The problem is that I then need to reference q
, r
, and s
twice when instantiating the case class:
A(0.5, 1.0, 2.0, List(f1(3.0), f2(4.0, 0.5))) //0.5 is referenced twice
I would like to be able to instantiate the class like this:
A(0.5, 1.0, 2.0, List(f1(3.0), f2(4.0))) //f2 already knows about q!
What is the best technique to accomplish this? Can I define my functions in a trait that the case class extends?
EDIT: The real world application has 7 members, not 3. Only a small number of the func开发者_开发百科tions need access to the members. Most of the functions don't care about them.
If q
in f2
is always referring to the q
in you case class
, then one quick hack :
trait TraitA {
def q:Double
def r:Double
def s:Double
def f1(w:Double) = (d:Double) => math.sin(d) * w
def f2(w:Double) = (d:Double) => d * q * w
}
case class A(q:Double, r:Double, s:Double, l:List[(Double)=>Double]=Nil) extends TraitA
val a=new A(0.5, 1.0, 2.0){override val l= List(f1(3.0), f2(4.0))}
There's the obvious val declaration:
val a = 0.5
A(a, 1.0, 2.0, List(f1(3.0), f2(4.0, a)))
Otherwise, f2
needs a reference to A's this
, which it will have if it's a member of class A or that particular instance of A. Part of the problem is that the functions are fully baked before the instance of A is instantiated. So you have to define f2
, as opposed to simply instantiate it, in the context of A.
Finally, you could make the functions partial functions. The first group of params will be as they are, but a second group will be added that is of type A.
One simple idea would be to change the function to take a list of functions that take 3 doubles (q, r, and s) and return a function from double to double. That way those functions that need any of the values can use them, and others just ignore them all.
精彩评论