当我想使用隐式方法将函数转换为其他内容时,我遇到了一些问题。
我正在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 _)
语法并仍然使用含义?
答案 0 :(得分:6)
Scala要求您编写(b _)以确保您确实希望将方法b装箱为函数值。如果您不想编写下划线,请直接将b定义为函数值而不是方法:
val b = (a: A) => a.b
答案 1 :(得分:4)
问题发生是因为b
不是函数,而是方法。请查看有关该主题的相关问题。但是,如果您定义下面的b
,则不应该有任何问题:
def b = (_: A).b
这将b
的类型定义为函数。