Прокачай мою функцию в scala - применяя неявные преобразования к функциям - PullRequest
3 голосов
/ 20 июля 2010

У меня возникают некоторые проблемы, когда я хочу использовать неявные методы для преобразования функции во что-то другое.

Я реализую небольшой DSL в Scala 2.8 для целей тестирования.Он должен поддерживать различные проверки (утверждения, если хотите) на экземплярах.Весь DSL немного сложен, но следующий упрощенный пример показывает мою проблему:

object PimpMyFunction {

  class A(val b: Int)

  def b(a: A) = a.b

  class ZeroCheck(f: A => Int) {
    def isZeroIn(a: A) = f(a) == 0
  }

  implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)     

  def main(args: Array[String]) {
    val a0 = new A(0)
    val a1 = new A(1)

    println(fToCheck(b).isZeroIn(a0))
    println(fToCheck(b).isZeroIn(a1))

    println(b.isZeroIn(a0)) 
  }
}

Первые две строки println (когда я явно вызываю метод преобразования) компилируются и работают нормально, но последняя (когдаЯ хочу полагаться на имплициты) выдает ошибку:
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you want to treat it as a partially applied function
Если я хочу неявно конвертировать "нормальные" экземпляры (которые не являются функциями) так же, как это также работает, так что я думаю, что проблема не всвязанные с определением объема / импортом.

Если я следую инструкциям, приведенным в сообщении об ошибке, и использую println((b _).isZeroIn(a0)), оно также работает, но DSL ориентирован на не технических специалистов, поэтому я хотел бы сохранить синтаксис как можно более чистым и простым.

Я думаю, у меня есть другой обходной путь (b должен быть классом, расширяющим черту Assertions, которая уже содержит методы проверки + A => Int), который бы поддерживал более чистый синтаксис, но он был бы более подробным и менее гибкимпоэтому я бы предпочел неявный способ.

Есть идеи, как избежать синтаксиса (b _) и при этом использовать импликации?

Ответы [ 2 ]

6 голосов
/ 20 июля 2010

Scala требует, чтобы вы написали (b _), чтобы убедиться, что вы действительно хотите, чтобы метод b был помещен в значение функции. Если вы не хотите писать подчеркивание, то вместо метода непосредственно определите b как значение функции:

val b = (a: A) => a.b
4 голосов
/ 20 июля 2010

Проблема возникает из-за того, что b не функция, а метод. Пожалуйста, посмотрите связанные вопросы по этой теме. Если вы определите b, как показано ниже, у вас не должно возникнуть никаких проблем:

def b = (_: A).b

Определяет тип b как функции.

...