【问题标题】:Pimp my function in scala - applying implicit conversions on functions在 scala 中拉皮条我的函数 - 对函数应用隐式转换
【发布时间】:2010-07-20 08:55:43
【问题描述】:

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

出于测试目的,我正在 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 trait 的类,它已经包含检查方法 + A => Int),它将支持更简洁的语法,但它会更冗长且不太灵活,所以我更喜欢隐式的方式。

任何想法如何避免(b _) 语法并仍然使用隐式?

【问题讨论】:

    标签: scala scala-2.8 implicit


    【解决方案1】:

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

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

    【讨论】:

    • 通过部分应用将方法转换为函数的术语是“lift”或“lifting”。
    • 就像一个魅力,就像丹尼尔的解决方案一样。我认为两者之间没有显着差异,您的优先 -> 这就是我接受的,即使它们都完美地解决了我的问题。感谢您的两个答案。
    【解决方案2】:

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

    def b = (_: A).b
    

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

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 1970-01-01
      • 2016-07-25
      • 2015-02-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 2017-08-28
      • 2017-03-11
      相关资源
      最近更新 更多