3

当我想使用隐式方法将函数转换为其他函数时,我遇到了一些问题。

我在 Scala 2.8 中实现了一个小型 DSL 用于测试目的。它应该支持对实例的各种检查(如果你愿意,可以断言)。整个 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 _)语法并仍然使用隐式?

4

2 回答 2

6

Scala 要求您编写 (b _) 以确保您确实希望将方法 b 装箱为函数值。如果不想写下划线,直接定义 b 为函数值而不是方法:

val b = (a: A) => a.b
于 2010-07-20T10:37:49.993 回答
4

问题的发生是因为b不是函数,而是方法。请查找有关该主题的相关问题。但是,如果您b像下面这样定义,则应该没有任何问题:

def b = (_: A).b

这将类型定义为b函数。

于 2010-07-20T12:15:46.650 回答