FoldLeft/FoldRight: Scala Compile-Errors

49 Views Asked by At

Trying to finish up an assignment and running into the following compiler errors:

fp2.scala:144: error: not enough arguments for method foldRight: (xs: List[A], e: B, f: (A, B) => B)B.
Unspecified value parameter f.
    foldRight (xs, "")((a, b) => a + term + b)
              ^
fp2.scala:161: error: not enough arguments for method foldLeft: (xs: List[A], e: B, f: (B, A) => B)B.
Unspecified value parameter f.
    foldLeft (xs, "")((a, b) => a + b + term)
             ^
two errors found

The errors seem to be with the calls to these functions (i.e., foldRight, foldLeft, and joinTerminateRight and joinTerminatLeft, but it's not obvious to me (newbie with Scala and also with stackoverflow...so apologies if my format/style is out of line).

Source code is as follows:

// GENERATED
// SCALA 2.13.0  

/* INSTRUCTIONS
 *
 * Complete the exercises below.  For each "EXERCISE" comment, add
 * code immediately below the comment.
 *
 * Please see README.md for instructions, including compilation and testing.
 *
 * GRADING
 *
 * 1. Submissions MUST compile using SBT with UNCHANGED configuration and
 *    tests with no compilation errors.  Submissions with compilation errors
 *    will receive 0 points.  Note that refactoring the code will cause the
 *    tests to fail.
 *
 * 2. You MUST NOT edit the SBT configuration and tests.  Altering it in your
 *    submission will result in 0 points for this assignment.
 *
 * 3. You MUST NOT use while loops or (re)assignment to variables (you can
 *    use "val" declarations, but not "var" declarations).  You must use
 *    recursion instead.
 *
 * 4. You may declare auxiliary functions if you like.
 *
 */

import java.util.NoSuchElementException
object 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)
    }
}

New to debugging code in scala. The number and types of arguments seem right to me, so I'm at a bit of a loss currently on how to proceed.

1

There are 1 best solutions below

2
MartinHH On

foldLeft and foldRight (as defined in your exercise's code) each take three parameters in one parameter list (the list xs, the empty element e and the accumulator function f).

But when you call them (from within joinTerminateLeft and joinTerminateRight), you only pass two parameters to the first parameter list (xs and e), then close that parameter list (using )) and try to pass the accumulator function f into a second parameter list. Hence, the compiler complains that you did not pass the parameter f where it expects it (at the end of the first parameter list).

You could fix this by changing the signature for foldLeft/foldRight to have two parameter lists (e.g. def foldLeft [A, B] (xs: List[A], e: B)(f: ((B, A) => B)): B. But that would violate the rules of your assignment, so you need to fix it by passing the accumulator function as third parameter of the first parameter list.