FoldLeft/FoldRight:Scala 编译错误

问题描述 投票:0回答:1

尝试完成作业并遇到以下编译器错误:

fp2.scala:144: 错误:foldRight 方法参数不足:(xs: List[A], e: B, f: (A, B) => B)B。 未指定值参数 f。 FoldRight (xs, "")((a, b) => a + term + b) ^ fp2.scala:161: 错误:foldLeft 方法参数不足:(xs: List[A], e: B, f: (B, A) => B)B。 未指定值参数 f。 FoldLeft (xs, "")((a, b) => a + b + 项) ^ 发现两个错误

这些错误似乎与对这些函数的调用有关(即,foldRight、foldLeft、joinTerminateRight 和 joinTerminateLeft),但对我来说并不明显(Scala 和 stackoverflow 的新手......所以如果我的格式/样式已经过时,我深表歉意线)。

源代码如下:

// 已生成 // SCALA 2.13.0

/* 说明 *

  • 完成下面的练习。对于每个“EXERCISE”评论,添加
  • 代码紧接在评论下方。
  • 请参阅 README.md 了解说明,包括编译和测试。
  • 评分
    1. 提交内容必须使用配置未更改的 SBT 进行编译并且
  • 测试没有编译错误。提交有编译错误
  • 将获得 0 分。请注意,重构代码会导致
  • 测试失败。
    1. 您不得编辑 SBT 配置和测试。改变你的
  • 提交此作业将获得 0 分。
    1. 您不得使用 while 循环或(重新)分配变量(您可以
  • 使用“val”声明,但不使用“var”声明)。你必须使用
  • 用递归代替。
    1. 如果愿意,您可以声明辅助函数。

*/

导入java.util.NoSuchElementException 对象 fp2 {

// EXERCISE 1: complete the following recursive definition of a "map"
// function for Scala's builtin List type.  You must not use the builtin
// "map" method.
//
// Your implementation of "map" MUST be recursive.
def map[A, B](xs: List[A], f: A => B): List[B] = {
    // TODO: Provide definition here.
    xs match {
        case Nil => Nil
        case y :: ys => f (y) :: map (ys, f)
    }
}

// EXERCISE 2: complete the following recursive definition of a "filter"
// function for Scala's builtin List type.  You must not use the builtin
// "filter" method.
//
// Your implementation of "filter" MUST be recursive.
def filter[A](xs: List[A], f: A => Boolean): List[A] = {
    // TODO: Provide definition here.
    xs match {
        case Nil => Nil
        case y :: ys => if (f (y)) y :: filter (ys, f) else filter (ys, f)
    }
}

// EXERCISE 3: complete the following recursive definition of an "append"
// function for Scala's builtin List type.  You must not use the builtin
// ":::" method.
//
// Your implementation of "append" MUST be recursive.
//
// HINT: use "::" in the body of the cons-cell case.
def append[A](xs: List[A], ys: List[A]): List[A] = {
// TODO: Provide definition here.
    xs match {
        case Nil => ys
        case z :: zs => z :: append (zs, ys)
    }
}

// EXERCISE 4: complete the following recursive definition of a "flatten"
// function for Scala's builtin List type.  You must not use the builtin
// "flatten" method.
//
// Your implementation of "flatten" MUST be recursive.
//
// HINT: use either ":::" or your definition of "append" in the body of the
// cons-cell case.
//
// EXAMPLE:
// - flatten (List ((1 to 5).toList, (6 to 10).toList, (11 to 15).toList)) == (1 to 15).toList
def flatten[A](xss: List[List[A]]): List[A] = {
    // TODO: Provide definition here.
    xss match {
        case Nil => Nil
        case xs :: xss1 => append (xs, flatten(xss1))
    }
}

// EXERCISE 5: complete the following recursive definition of a "foldLeft"
// function for Scala's builtin list type.  You must not use the builtin
// "foldLeft" method.
//
// Your implementation of "foldLeft" MUST be recursive.
//
// HINT:   foldLeft (  Nil, e, f) == e
//         foldLeft (y::ys, e, f) == foldLeft (ys, f (e, y), f)
def foldLeft [A, B] (xs: List[A], e: B, f: ((B, A) => B)): B = {
    // TODO: Provide definition here.
    xs match {
        case Nil => e
        case y :: ys => foldLeft (ys, f(e, y), f)
    }
}

// EXERCISE 6: complete the following recursive definition of a "foldRight"
// function for Scala's builtin list type.  You must not use the builtin
// "foldRight" method.
//
// Your implementation of "foldRight" MUST be recursive.
//
// HINT:   foldRight (  Nil, e, f) == e
//         foldRight (y::ys, e, f) == f (y, foldRight (ys, e, f))
def foldRight [A, B] (xs: List[A], e: B, f: ((A, B) => B)): B = {
    // TODO: Provide definition here.
    xs match {
      case Nil => e
      case y :: ys => f (y, foldRight (ys, e, f))
    }
}

// EXERCISE 7: complete the following definition of a "joinTerminateRight"
// function to take a list of strings "xs" and concatenate all strings
// using a string "term" as a terminator (not delimiter) between strings.
//
// You MUST use your foldRight defined above.
//
// You MAY NOT use recursion.
//
// EXAMPLES:
// - joinTerminateRight (Nil, ";") == ""
// - joinTerminateRight (List ("a"), ";") == "a;"
// - joinTerminateRight (List ("a","b","c","d"), ";") == "a;b;c;d;"
def joinTerminateRight(xs: List[String], term: String): String = {   
    // TODO: Provide definition here.
    foldRight (xs, "")((a, b) => a + term + b)
}

// EXERCISE 8: complete the following definition of a "joinTerminateLeft"
// function to take a list of strings "xs" and concatenate all strings
// using a string "term" as a terminator (not delimiter) between strings.
//
// You MUST use your foldLeft defined above.
//
// You MAY NOT use recursion.
//
// EXAMPLES:
// - joinTerminateLeft (Nil, ";") == ""
// - joinTerminateLeft (List ("a"), ";") == "a;"
// - joinTerminateLeft (List ("a","b","c","d"), ";") == "a;b;c;d;"
def joinTerminateLeft(xs: List[String], term: String): String = {
    // TODO: Provide definition here.
    foldLeft (xs, "")((a, b) => a + b + term)
}

// EXERCISE 9: complete the following recursive definition of a
// "firstNumGreaterOrEqual" function to find the first number greater than or
// equal to "a" in a list of integers "xs".
//
// If the list is empty or there is no number greater than or equal to "a",
// throw a java.util.NoSuchElementException (with no argument).
//
// Your implementation of "firstNumGreaterOrEqual" MUST be recursive.
//
// EXAMPLES:
// - firstNumGreaterOrEqual (5, List (4, 6, 8, 5)) == 6
def firstNumGreaterOrEqual(a: Int, xs: List[Int]): Int = {
    // TODO: Provide definition here.
    xs match {
        case Nil => throw new NoSuchElementException
        case y :: ys => if (y >= a) y else firstNumGreaterOrEqual (a, ys)
    }
}

// EXERCISE 10: complete the following recursive definition of a
// "firstIndexNumGreaterOrEqual" function to find the index (position) of the
// first number greater than or equal to "a" in a list of integers "xs".
//
// The first index should be zero (not one).
//
// If the list is empty or there is no number greater than or equal to "a",
// throw a java.util.NoSuchElementException (with no argument).
//
// Your implementation of "firstIndexNumGreaterOrEqual" MUST be recursive.
//
// EXAMPLES:
// - firstIndexNumGreaterOrEqual (5, List (4, 6, 8, 5)) == 1
//
// HINT: this is a bit easier to write if you use an auxiliary function.
def firstIndexNumGreaterOrEqual(a: Int, xs: List[Int]): Int = {
    // TODO: Provide definition here.
    def aux(count: Int, list: List[Int]): Int = list match {
        case Nil => throw new NoSuchElementException
        case y :: ys => if (y >= a) count else aux (count + 1, ys)
    }
    aux (0, xs)
}

}

在 scala 中调试代码的新手。参数的数量和类型对我来说似乎是正确的,所以我目前对如何进行有点不知所措。

list scala recursion compiler-errors fold
1个回答
0
投票

foldLeft
foldRight
(如练习代码中所定义)各自采用一个参数列表中的三个参数(
list
、空元素
e
和累加器函数
f
)。

但是当您调用它们时(从

joinTerminateLeft
joinTerminateRight
中),您只需将两个参数传递到第一个参数列表(
list
e
),然后关闭该参数列表(使用
)
)并尝试将累加器函数
f
传递到第二个参数列表中。因此,编译器抱怨您没有将参数
f
传递到它期望的位置(在第一个参数列表的末尾)。

您可以通过更改

foldLeft
/
foldRight
的签名来修复此问题,使其具有两个参数列表(例如
def foldLeft [A, B] (xs: List[A], e: B)(f: ((B, A) => B)): B
)。但这会违反您的分配规则,因此您需要通过将累加器函数传递为第一个参数列表的第三个参数。

© www.soinside.com 2019 - 2024. All rights reserved.