在scala中使用我的函数 - 在函数上应用隐式转换

时间:2010-07-20 08:55:43

标签: scala scala-2.8 implicit

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

我正在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行(当我显式调用转换方法时)编译并正常工作,但最后一行(当我想依赖于implicits时)会产生错误:
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 个答案:

答案 0 :(得分:6)

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

val b = (a: A) => a.b

答案 1 :(得分:4)

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

def b = (_: A).b

这将b的类型定义为函数。