在 scala 中拉皮条我的函数 - 在函数上应用隐式转换

发布于 2024-09-10 13:44:09 字数 1036 浏览 1 评论 0原文

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

我正在 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技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴我心暖 2024-09-17 13:44:09

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

val b = (a: A) => a.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:

val b = (a: A) => a.b
携君以终年 2024-09-17 13:44:09

出现问题是因为 b 不是函数,而是方法。请查找该主题的相关问题。不过,如果您像下面这样定义 b ,就不会有任何问题:

def b = (_: A).b

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

The problem happens because b is not a function, but a method. Please look up related questions on that topic. If you define b like below, though, you shouldn't have any problems:

def b = (_: A).b

This defines the type of b to be a function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文