在Scala中提取独立函数的方法

Hug*_*ira 6 oop functional-programming scala scala-macros

给出如下内容:

class A {
  def f(x: X) = ...
  def g(y: Y, z: Z) = ...
  ...
}
Run Code Online (Sandbox Code Playgroud)

如何(自动)提取功能:

object A {
  val f' = (a: A, x: X) => a.f(x)  // do this automagically for any arbitrary f
  val g' = (a: A, y: Y, z: Z) => a.g(y, z) // and deal with arity > 1 too
  ...
}
Run Code Online (Sandbox Code Playgroud)

使用此精确类型签名(首先是对象,然后是参数列表).让我非常清楚地说明问题:

"给定的方法f(x1: X1, ..., xn: Xn)中的一类的上下文中定义A,如何自动提取功能f'的是(ⅰ) 接收一个实例a类型的A,和(ⅱ)相当于1的参数列表:1到的参数列表中f,即x1: X, ... xn: Xn,其实施正是a.f(x1: X1, ..., xn: Xn)"

甚至:

捕获lambda-calculus 的可扩展概念,这样你就可以自动?x.(f x)f任何时候x 自由地提取出来f.

这可以首先通过找到一种方法访问标识符来解决f,g......不具有特定的a: A(一个将有一个具体的A以后,当然).我们可以简单地写f'g'手工,但让我们放纵干燥.


PS如果没有运行时反射,这是不可能的(尽管可能使用Scala 2.10+宏),因为我似乎无法预先找到一种方法来引用fg不引用特定实例(a: A)的标识符.但它将类似于以下内容,而不必诉诸strings:

A.getMethod("f"): Function2[A, X, ...]
Run Code Online (Sandbox Code Playgroud)

我也意识到问题的实际应用可能有助于参与者提出替代方案,但我是在抽象意义上讨论这个问题.我不是要解决我已经减少到这个问题的其他问题.我想知道这个是否可能:-)这是一篇非常好的文章,可以真正理解这个问题背后的动机,对Scala的Eta扩展进行咆哮.

Pau*_*her 2

您当然可以在编译时使用宏来执行此操作 - 我在ScalaMock 3 预览版中做了类似的事情- 模拟对象是匿名类的实例,其中每个成员都由模拟函数的实例实现。您很可能可以将其用作您想要做的事情的起点。

警告:ScalaMock 3 目前仅适用于 Scala 2.10.0-M6。它不适用于 M7 或当前的开发版本,因为我还没有机会解决宏 API 中的重大更改。