是否有可能在斯卡拉相反的方式?

时间:2009-12-17 11:04:47

标签: scala functional-programming currying

我们假设这个功能:

def autoClosing(f: {def close();})(t: =>Unit) = {
    t
    f.close()
}

和此代码段:

val a = autoClosing(new X)(_)
a {
 println("before close")
}

有可能咖喱第一部分吗?类似的东西:

val a = autoClosing(_) { println("before close") }

这样我就可以发送应该执行close的对象,并在它们上执行相同的块?

3 个答案:

答案 0 :(得分:10)

是的,只要您提供占位符字符的类型,您提供的代码段就可以使用。

因此,您正在寻找的代码是:

val a = autoClosing(_: {def close();}) { println("before close") }

编译并按预期工作:)。

几点说明:

  • 如果您为具有AnyRef方法的close类型定义类型别名,例如type Closeable = AnyRef {def close()}或适当的界面,则可以让您的生活更轻松。
  • 代码段autoClosing(_: Closeable){ ... }实际上等同于以下扩展的匿名函数:c: Closeable => autoClosing(c){ ... }。通配符只是部分应用函数的简写。您需要提供_的类型,因为在这种情况下,类型推断器无法推断出类型。

希望它有所帮助,

- Flaviu Cipcigan

答案 1 :(得分:6)

或者你可以翻转参数:

def flip[A1, A2, B](f: A1 => A2 => B): A2 => A1 => B = x1 => x2 => f(x2)(x1)

在你的情况下:

val a = flip(autoClosing){ println("before close") }

编辑: 我添加了一些大括号来帮助人工解析器:

def flip[A1, A2, B](f: (A1 => (A2 => B))): (A2 => (A1 => B)) = {
    x1 => (x2 => f(x2)(x1))
}

翻转将函数(A1 => (A2 => B))转换为(A2 => (A1 => B))

scala> def x(x1 : Int)(x2 : Long) = 1.0 * x1 / x2
x: (Int)(Long)Double

scala> val f = flip(x)
f: (Long) => (Int) => Double = <function>

scala> val g = f(1)
g: (Int) => Double = <function>

scala> val h = g(2)
h: Double = 2.0

scala> x(1)(2)
res0: Double = 0.5

答案 2 :(得分:3)

我很高兴现在有很多人回答斯卡拉问题。然而,它确实让我更难想出一些东西。这是Flaviu solution的替代方法。

val a: {def close();} => Unit = autoClosing(_) { println("before close") }

当然,正确的解决方案是以与您将如何使用它的方式相同的方式定义autoClosing。