Reputation: 34403
I have a class implementing some functionality (providing a turtle graphics interface for L-systems, but that is not important here):
abstract class LSystem
{
def BranchBegin()
def BranchEnd()
def Rotate(axis:Vector3f, angle:Float)
def MoveForward(dist:Float)
def DrawForward(size:Float, color:ColorRGBA)
def DrawSphere(size:Float, color:ColorRGBA)
}
I have a a trait prodiving some helpers:
trait LSystemShortcuts {
def < ()(implicit lsys:LSystem)= lsys.BranchBegin()
def S(size:Float, color:ColorRGBA)(implicit lsys:LSystem)= lsys.DrawSphere(size,color)
def > ()(implicit lsys:LSystem)= lsys.BranchEnd()
}
And finally there is an individual L-system, looking like this:
class RoundTree(implicit lsys:LSystem) extends LSystemShortcuts {
// TODO: move to LSystemShortcuts
def F = lsys.DrawForward _
def R = lsys.Rotate _
def M = lsys.MoveForward _
val degree = PI.toFloat/180
val colorCrown = ColorRGBA.SRGB(0.1f,0.4f,0.05f, 1)
val colorTrunk = ColorRGBA.SRGB(0.1f,0.1f,0.05f,1)
def C(size:Float, iterations:Int) = {
if (iterations>0) {
F(size*0.5f,colorTrunk)
<
C(size*0.5f,iterations-1)
>
<
R(Vector3f(0,0,1),+75*degree)
C(size*0.3f,iterations-1)
>
// some more rendering code here
}
else
{
F(size,colorTrunk)
M(size*0.6f)
S(size*0.7f,colorCrown)
}
}
}
Note that currently shortcuts F
, R
and M
are defined directly in the RoundTree
class. I would like to move it to the LSystemShortcuts
trait, but I would like to avoid having to repeat the argument lists (this is currently done by using partially applied function), like it was done for S shortcut. It would be easy to use LSystemShortcuts
as a base class instead, but I do not like such design, trait seems more appropriate.
Is there some way to forward argument lists when defining functions? Something along lines of:
def R(_)(implicit lsys:LSystem) = lsys.Rotate _
Or perhaps some other design, having LSystemShortcuts
as a member instead of a trait, which would allow me to achive that?
Upvotes: 0
Views: 118
Reputation: 3608
Well, I can guess of a kind of a dirty workaround. You could alter the definition of your trait
with a protected member.
trait A {
protected var i: Int = 0 // has to be initialized, won't compile otherwise
def print = println(i)
}
Afterwards you could use that member as follows:
class B extends A {
i = 10
print
}
A call of new B()
will print 10
to the console.
I hope this answers your question as intended. Otherwise I will be glad to try and work out another solution.
Upvotes: 1
Reputation: 108101
To my knowledge this is not possible, since scala does not support point-free style notation as Haskell does.
I'm afraid there's no way of passing the arguments other than explicitly.
Upvotes: 0