/ / Scala - DSL: przeciążona niejednoznaczność funkcji przedrostka - scala, dsl, przeciążenie metody, curry

Scala - DSL: niejednoznaczna funkcja przedrostka funkcji - scala, dsl, przeciążanie metod, currying

W mojej DSL chcę tę funkcjonalność:

class Test {

val compA = dependant(true, true)(Component("parameters"))

//and this shortcut:

val compB = dependant Component("parameters")
}

gdzie:

def dependant(onEnable: Boolean, onDisable: Boolean)(c: Component): Component = {
//...
}

def dependant(c: Component): Component = dependant(false, true)(c)

wszystko jest w porządku, jednak nie mogę użyć tej składni:

val compB = dependant Component("parameters")

ponieważ to mówi

dwuznaczne odniesienie do przeciążonej definicji,obie metody zależą od test klasy typu (onEnable: Boolean, onDisable: Boolean) (c: Składnik) Składnik i metoda zależne od klasy Badanie typu (c: Komponent) Komponent pasuje do oczekiwanego typu?

Ale jeśli dołączę parametr w nawiasie:

val compB = dependant(Component("parameters"))

błąd zniknął. Oczywiście kompilator nie potrafi rozdzielić przypadku bez nawiasów. Czy jest to oczekiwane, czy robię coś złego? Jeśli jest to oczekiwane, to dlaczego? Jak mogę odzyskać umiejętność korzystania z tej metody? dependant jako przedrostek, bez nawiasów?

Odpowiedzi:

2 dla odpowiedzi № 1

W dependant Component("parameters") próbujesz użyć notacji przedrostkowej, aby wywołać numer dependant. Obsługa Scali w zakresie notacji prefiksów jest ograniczona.

Widzieć Scala - Przedrostek Unary Operators.

Alternatywą jest użycie notacji postfiksowej (jak w Component("parameters") dependant). Jeśli możesz zmodyfikować implementację Componenet, oznacza to po prostu dodanie dependant metody do Component:

class Component(name: String) {
def dependant: Component = //...
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}

class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}

Jeśli nie możesz zmodyfikować Component, możesz użyć „pimp my idiom Library”. Widzieć http://www.decodified.com/scala/2010/12/02/the-quickpimp-pattern.html za krótkie wprowadzenie do tego idiomu (wraz z ostrzeżeniem o używaniu anonimowej klasy, jak poniżej):

case class Component(name: String)

implicit def toPostifxDependentOps( c: Component ) = new {
def dependant: Component = dependant(false, true)
def dependant(onEnable: Boolean, onDisable: Boolean): Component = {
//...
}
}

class Test {
val compA = Component("parameters") dependant(true, true)
val compB = Component("parameters") dependant
}

2 dla odpowiedzi nr 2

Pisanie myObject functionName paramzamiast myObject.functionName(param) działa zgodnie z oczekiwaniami, jeśli zaproponujesz obiekt. Jeśli tego nie zrobisz, kompilator zostanie utracony. Na przykład:

scala> println("Hello")
Hello

scala> println "Hello"
<console>:1: error: ";" expected but string literal found.
println "Hello"
^

Możliwe obejście: utwórz obiekt, aby zawinąć metodę:

scala> case class Component(name: String, components: Option[Component] = None)
defined class Component

scala> object depends {def on(c: Component) = Component("dependant", Some(c))}
defined module depends

scala> depends on Component("foo")
res3: Component = Component(dependant,Some(Component(foo,None)))