Методы импорта для объекта в Scala - PullRequest
3 голосов
/ 21 марта 2019

Я пытаюсь написать DSL со Scala.Сначала я хотел бы иметь возможность писать такие вещи, как

   defType "foo"

при его использовании.

Я думал, что должно работать следующее:

src / main / scala / Test.scala

class Dsl {
    def defType(name: String) = "dummy"
}
object Dsl {
    def apply() = new Dsl()
}

class UseDsl {
    def foo() = {
        val dsl = Dsl()
        import dsl._

        dsl defType "foo"
        defType("foo")
        defType "foo"
    }
}

Это не компилируется:

[error] Test.scala:15:17: ';' expected but string literal found.
[error]         defType "foo"
[error]                 ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Явное указание dsl работает с пробелами для разделения имен методов и аргументов.

Неявное использование dsl и скобок для указания аргументов против имен методов работает.

Попытка использовать их вместе не удалась.

Есть ли способ заставить это работать?

Как только это заработает, я планирую расширить DSL для поддержки таких вещей, как

defType "foo"
   -- "bar1" :: "quz"
   -- "bar2" :: "quz"

, что эквивалентно

dsl.defType("foo").
   --(ImplicitClass("bar1", dsl).::("quz")).
   --(ImplicitClass("bar2", dsl).::("quz"))

Это то, что я смогу заставить работать?Я думаю, что ImplicitClass будет работать с декларацией вроде

def implicit ImplicitClass(a: String, implicit dsl: Dsl) = ...

, но ясно, что мое понимание того, как вы можете заставить Scala добавлять элементы в ваш код, несовершенно.

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

build.sbt

ThisBuild / organization := "test"
ThisBuild / version := "0.0.1-SNAPSHOT"
ThisBuild / scalaVersion := "2.12.8"


//
// Projects
//
lazy val root = (project in file("."))

1 Ответ

1 голос
/ 21 марта 2019

Нет, method argument недействительно. Для вызовов инфиксных методов без круглых скобок у вас есть для выполнения

val1 method1 val2 method2 val3 ...

Эта цепочка может заканчиваться на методе без аргументов или на последнем аргументе метода, а первый не слишком безопасен.

Даже для членов текущего типа вам нужно сделать this method1 ... и не можете пропустить this, как в this.method1(...).

...