【问题标题】:Scala: currying conceptsScala:柯里化概念
【发布时间】:2015-08-17 06:53:41
【问题描述】:

我正在通过练习“不耐烦的 Scala”一书中的练习来学习 Scala。有几个问题可以测试柯里化的概念。我已尽我所能回答了这些问题,但我想由这里的专家来运行这些问题。

调用corresponds 来检查 字符串数组的长度在整数数组中给出。

我的代码:

def isCorrespondingLength(arr: Array[String], len: Array[Int]) = {
  arr.corresponds(len)(_.length == _)
}

在不使用柯里化的情况下实现corresponds。然后尝试从 以前的练习。你遇到了什么问题?

Ans:编译器不能像上一个练习那样使用下划线派生类型。

def myCorresponds(arr: Array[String], that: Seq[Int], f: (String, Int) => Boolean) = {
  arr.zip(that).find(p => f.apply(p._1, p._2)).isDefined
}

实现一个类似于if 的unless 控制抽象, 但有一个倒置的条件。第一个参数是否需要是 按名称调用参数?你需要咖喱吗?

Ans:第一个参数不需要是按名称调用的参数。由于它只评估一次,因此评估是在调用站点(如按值调用)还是在函数内部(按名称调用)发生都不会影响结果。柯里化,如unless2,提供了一个很好的控制抽象unless2(false) { block },但这不是必需的。

 def unless(condition: () => Boolean, block: => Boolean): Boolean = {
   if (!condition()) block else false
 }

 def unless2(condition: => Boolean)(block: => Boolean): Boolean = {
   if (!condition) block else false
 }

【问题讨论】:

    标签: function scala closures currying higher-order-functions


    【解决方案1】:
    def isCorrespondingLength(arr: Array[String], len: Array[Int]) = {
      myCorresponds(arr, len, _.length == _)
    }
    

    编译得很好。现在考虑如果您将myCorresponds 设为通用(即使用A 和B 而不是String 和Int)会发生什么。

    【讨论】:

    • isCorrespondingLength 用下划线编译,但 myCorresponds 没有。 arr.zip(that).find(f).isDefined 或 arr.zip(that).find(p => f.apply(_ , _)).isDefined 无法编译。
    • 在第一种情况下,f 必须是一个函数,它需要一个 (String, Int) 参数来编译而不是两个参数;在第二个 p => f.apply(_ , _) 根本不是你想要的(它相当于 p => { (q, r) => f.apply(q, r) }。但它们与你问题中的工作版本之间的区别不是柯里化。
    猜你喜欢
    • 2018-01-24
    • 2021-02-07
    • 1970-01-01
    • 2021-03-11
    • 2011-11-03
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多