Scala DSL, объектная и инфиксная нотация

в Scala, если я хочу реализовать DSL, есть ли способ сделать следующее:

У меня есть объект под названием «Рисование», который содержит функцию def draw(d:Drawable)

как я могу сделать так, чтобы я мог импортировать объект и вызывать его вне объекта, например:

draw ball

если мяч расширяет черту Drawable? Проблема в том, что я хочу использовать отрисовку в своего рода инфиксной нотации, но я не хочу квалифицировать отрисовку функции, обозначая ее реализующий класс/объект.


person Felix    schedule 19.05.2010    source источник
comment
Следующий поток может пролить свет на это: stackoverflow.com/questions/1006967/ Подводя итог: для инфиксных или унарных операторов можно использовать только ~, !, - и +, но не draw.   -  person Michel Krämer    schedule 20.05.2010


Ответы (2)


Я быстро попробовал это, но вполне мог заставить его работать, используя объект. Там мне пришлось использовать draw(ball) вместо draw ball, как вы хотели:


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

Однако, определив Draw как класс, это сработало:


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

Я не совсем уверен, почему это не работает так же с объектом, может быть ошибка или, возможно, это заданное поведение. Однако у меня не было времени, чтобы посмотреть это в данный момент.

person Arjan Blokzijl    schedule 19.05.2010
comment
Проблема с вашей первой версией заключается в том, что нотация оператора Scala требует явного получателя, поэтому пример класса работает. - person Mirko Stocker; 20.05.2010
comment
Я думаю, что синтаксис draw(ball) может быть приемлемым. У меня было бы что-то вроде рисования (мяча) в (x, y, z) на какой-то OpenGlPanel. В любом случае, это всего лишь тест на маленьком DSL :) Спасибо за ваш ответ. Кстати: может быть, можно было бы принять какой-нибудь символ-наполнитель, например, Draw -> ball или что-то еще... вернемся к размышлениям :) - person Felix; 20.05.2010
comment
Другим вариантом было бы переименовать метод рисования в. Таким образом, ваш пример будет выглядеть следующим образом: Нарисуйте мяч - person Paolo; 07.01.2014

Вы не можете этого сделать. Помимо четырех префиксных операторов, в любой нотации оператора первый токен представляет объект.

person Daniel C. Sobral    schedule 19.05.2010
comment
На самом деле Феликс мог сделать это, сделав draw объектом, а ball методом анонимного класса неявного преобразования, ссылающегося на реальный объект. Я сомневаюсь, что он или кто-либо другой предпочел бы это, поэтому +1 за этот ответ. - person Rex Kerr; 20.05.2010