开发者

Accessing a Class Member from a First-Class Function

开发者 https://www.devze.com 2022-12-30 23:36 出处:网络
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 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号