【问题标题】:Curry in scala with parametric types带有参数类型的scala中的咖喱
【发布时间】:2016-03-20 11:58:30
【问题描述】:

Functional Programming in Scala 的作者give this 作为 scala 中curry 的定义:

def curry[A,B,C](f: (A, B) => C): A => (B => C) =
    a => b => f(a, b)

但是,如果我们将其应用于采用参数类型的函数,例如:

def isSorted[A](as: Array[A], ordered:(A,A)=>Boolean) =
    if(as.size < 2)
        true else
           as.zip(as.drop(1)).map(ordered.tupled).reduce(_ && _)

那么结果想要A(在isSorted)什么都不是:

scala> curry(isSorted)
res29: Array[Nothing] => (((Nothing, Nothing) => Boolean) => Boolean) = <function1>

这显然不是我们想要的。 curry 应该被不同地定义,或者被不同地调用,还是在 Scala 中实现 curry 是不切实际的?

【问题讨论】:

  • 所以你想测试你的 isSorted 方法?
  • 不,我想对带有类型参数的函数使用 curry。

标签: scala functional-programming currying


【解决方案1】:

您在这里遇到了两个不同的问题。第一个是isSorted在传递给curry时被强制变成单态。第二个是 Scala 的类型推断在这里失败了。

这是 function and a method 之间的区别在 Scala 中很重要的时期之一。 isSorted 被 eta 扩展为一个函数,该函数又是一个 Scala 值,而不是一个方法。 Scala 的值总是单态的,只有方法可以是多态的。对于(A, B) C 类型的任何方法(这是method type 的语法,与(A, B) =&gt; C 不同,(A, B) =&gt; C 是一个函数,因此是一个值),默认的 eta-expansion 将导致所有函数的超类那个arity,即(Nothing, Nothing) =&gt; Any。这对您看到的所有Nothings 负责(您没有任何Anys,因为isSorted 的返回值是单态的)。

尽管 Scala 值具有单态性,但您可能会想像,理想情况下您可以执行类似

的操作
def first[A, B](x: A, y: B): A = x
curry(first)(5)(6) // This doesn't compile

这是 Scala 的本地类型推断让您感到困扰。它适用于从左到右的单独参数列表first 是推断类型的第一件事,如上所述,它被推断为(Nothing, Nothing) =&gt; Any。这与随后的Ints 发生冲突。

正如您所意识到的,解决此问题的一种方法是注释您传递给curry 的多态方法,以便它扩展为正确的类型。这几乎可以肯定是要走的路。

您可以做的另一件事(尽管我认为它除了教学目的之外没有任何作用)是 curry curry 本身并将其定义如下:

def curryTwo[A, B, C](x: A)(y: B)(f: (A, B) => C): C = f(x, y)

一方面,由于从左到右的类型推断,下面的代码现在有效。

curryTwo(5)(6)(first) // 5

另一方面,要在您想要使用curry 的场景中使用curryTwo,无论如何您都需要为Scala 的类型推断引擎提供类型。

【讨论】:

  • 谢谢!这很有教育意义。
【解决方案2】:

原来我可以这样称呼咖喱:

curry(isSorted[Int])

产量:

scala> curry(isSorted[Int])
res41: Array[Int] => (((Int, Int) => Boolean) => Boolean) = <function1>

https://stackoverflow.com/a/4593509/21640

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 1970-01-01
    • 2013-08-26
    • 2016-04-27
    • 2011-04-21
    • 2017-08-28
    • 2012-10-16
    • 2011-09-09
    • 1970-01-01
    相关资源
    最近更新 更多