Scala DSL, Object and infix notation
-
01-10-2019 - |
Question
in Scala, if I want to implement a DSL, is there a way to do the following:
I have an Object called "Draw" which contains the function def draw(d:Drawable)
how can I make it so that I can import the Object and call it outside the object like:
draw ball
if ball extends the Drawable trait? The problem is that I want to use draw in a kind of infix notation, but I dont want to qualify the function draw by denoting it's implementing class/object.
Solution
I quickly tried it out, but could quite make it work using an object. There I had to use draw(ball) instead of draw ball, as you wanted:
Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
scala> trait Drawable{def doSomething}
defined trait Drawable
scala> object Draw {
def draw(d:Drawable) = d.doSomething
}
defined module Draw
scala> val ball = new Drawable{def doSomething = println("doing ball")}
ball: java.lang.Object with Drawable = $anon$1@3a4ba4d6
scala> import Draw._
import Draw._
scala> draw ball
:11: error: missing arguments for method draw in object Draw;
follow this method with `_' if you want to treat it as a partially applied function
draw ball
^
scala> draw(ball)
doing ball
However by defining Draw as a class, it did work:
scala> trait Drawable{def doSomething: Unit}
defined trait Drawable
scala> class Draw {
def draw(d:Drawable) = d.doSomething
}
defined class Draw
scala>
scala> val ball = new Drawable{def doSomething = println("doing ball")}
ball: java.lang.Object with Drawable = $anon$1@36a06816
scala> val d = new Draw
d: Draw = Draw@7194f467
scala> d draw ball
doing ball
I'm not completely sure why this doesn't work the same way with an object, might be a bug or perhaps that's specified behaviour. However I didn't have the time to look it up at the moment.
OTHER TIPS
You can't do it. Aside from four prefix operators, in any operator notation the first token represents the object.