在 scala 中拉皮条我的函数 - 在函数上应用隐式转换
当我想使用隐式方法将函数转换为其他内容时,我遇到了一些问题。
我正在 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(当我显式调用转换方法时)编译并工作正常,但最后一行(当我想依赖隐式时)生成错误:编译错误:对象 PimpMyFunction 中方法 b 缺少参数;如果您想将其视为部分应用的函数,请在此方法后面加上“_”
如果我想以同样的方式隐式转换“正常”实例(不是函数),那么我想问题与范围界定/导入无关。
如果我按照错误消息的说明操作并使用 println((b _).isZeroIn(a0))
它也可以工作,但是 DSL 是针对非技术人员的,所以我想保留语法尽可能干净和简单。
我认为我有另一种解决方法(b 应该是一个扩展断言特征的类,它已经包含检查方法 + A => Int),它将支持更清晰的语法,但它会更冗长且不太灵活,所以我更喜欢隐式的方式。
有什么想法可以避免使用 (b _)
语法并仍然使用隐式吗?
I have some problems when I want to use implicit methods to convert a function to something else.
I'm implementing a small DSL in Scala 2.8 for testing purposes. It should support various checks (assertions if you like) on instances. The whole DSL is a bit complex, but the following simplified example shows my problem:
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))
}
}
First two println lines (when I explicitly call the conversion method) compile and work fine, but the last one (when I want to rely on implicits) produces the error: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
If I want to implicitly convert "normal" instances (which are not functions) the same way it also works, so I guess the problem is not related to scoping/importing.
If I follow the instructions of the error message and use println((b _).isZeroIn(a0))
it also works, but the DSL is targeted at non technical people, so I would like to keep the syntax as clean and simple as possible.
I think I have another workaround (b should be a class extending an Assertions trait which already contain the check methods + A => Int) that would support the cleaner syntax, but it would be more verbose and less flexible, so I would prefer the implicit way.
Any ideas how to avoid the (b _)
syntax and still use implicits?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Scala 要求您编写 (b _) 以确保您确实希望将方法 b 装箱到函数值。如果不想写下划线,直接将b定义为函数值而不是方法:
Scala requires you to write (b _) to ensure that you really want the method b to be boxed to a function value. If you don't want to write the underscore, directly define b to be a function value instead of a method:
出现问题是因为
b
不是函数,而是方法。请查找该主题的相关问题。不过,如果您像下面这样定义b
,就不会有任何问题:这将
b
的类型定义为函数。The problem happens because
b
is not a function, but a method. Please look up related questions on that topic. If you defineb
like below, though, you shouldn't have any problems:This defines the type of
b
to be a function.