代码之家  ›  专栏  ›  技术社区  ›  Sandor Murakozi

scala中的pimp my函数-对函数应用隐式转换

  •  3
  • Sandor Murakozi  · 技术社区  · 14 年前

    当我想使用隐式方法来转换 功能 去别的地方。

    为了测试的目的,我在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应该是一个扩展断言特性的类,该特性已经包含了check方法+A=>int),它支持更清晰的语法,但是它会更冗长、更不灵活,所以我更喜欢隐式方法。

    有什么办法可以避免 (b _) 语法和仍然使用暗示?

    2 回复  |  直到 14 年前
        1
  •  6
  •   Ruediger Keller    14 年前

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

    val b = (a: A) => a.b
    
        2
  •  4
  •   Daniel C. Sobral    14 年前

    问题的发生是因为 b 不是函数,而是方法。请查阅该主题的相关问题。如果你定义 不过,如下图所示,您不应该有任何问题:

    def b = (_: A).b
    

    这定义了 成为一个函数。

    推荐文章