【问题标题】:Is it possible to curry the other way around in Scala?是否可以在 Scala 中以另一种方式进行咖喱?
【发布时间】:2010-12-27 14:51:38
【问题描述】:

让我们假设这个函数:

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

还有这个sn-p:

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

可以咖喱第一部分吗?比如:

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

以便我可以发送应该执行关闭的对象,并在它们上执行相同的块?

【问题讨论】:

    标签: scala functional-programming currying


    【解决方案1】:

    是的,你给的sn-p是有效的,只要你给占位符的类型。

    因此,您要查找的代码是:

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

    按预期编译和工作:)。

    几点说明:

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

    希望对你有帮助,

    -- 弗拉维乌·西普西根

    【讨论】:

    • 不客气。添加了一些注释来扩展我的答案:)。不幸的是,类型推断器无法在此处推断通配符的类型。
    【解决方案2】:

    您也可以翻转参数:

    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))
    }
    

    Flip 将函数 (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
    

    【讨论】:

    • 你能解释一下那个怪物吗? :)
    • 我添加了一些花括号和示例代码,以便查看部分应用程序的实际应用。希望这会有所帮助。
    【解决方案3】:

    我很高兴看到现在有这么多人回答 Scala 问题。然而,这确实让我更难想出一些东西。这是Flaviusolution 的替代方案。

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

    当然,正确的解决方案是以与您将要使用的方式兼容的方式定义 autoClosing。

    【讨论】:

    • 我也很高兴 :)。我要放弃 Ruby 转而使用 Scala……它拥有我想要的一切语言。
    猜你喜欢
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2012-11-26
    • 2018-02-11
    • 2013-08-26
    • 2016-10-20
    相关资源
    最近更新 更多