0

Suppose you have the following functions available for reference

sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

Now consider the following dropWhile function which supposedly removes elements from List prefix as long as they match a predicate.

def dropWhile[A](l: List[A], f: A => Boolean): List[A] =
  l match {
    case Cons(h, t) if f(h) => dropWhile(t, f)
    case _ => l
  }

I have the following test cases:

dropWhile(List(1, 2, 3), (x: Int) => x < 2) shouldBe List(2, 3)

dropWhile(List(1, 2, 3), (x: Int) => x > 2) shouldBe List(1, 2)

dropWhile(List(1, 2, 3), (x: Int) => x > 0) shouldBe Nil

dropWhile(Nil, (x: Int) => x > 0) shouldBe Nil

Question?

Test case (2) fails. Why is that the case?. The interpreter actually gives me List(1, 2, 3) the original list without having dropped anything.

For context this is Exercise 3.5 on Functional Programming in Scala by Chuisano and Bjarnason. The authors themselves implement this function exactly the same way I have written on here. Is there something that I am not understanding here?.

Kid Charlamagne
  • 558
  • 1
  • 10
  • 27

1 Answers1

4

Test case (2) is wrong. You are dropping elements while x > 2. Since the first element fails this test, it does not drop anything. So List(1, 2, 3) is the correct result.

The test case appears to be testing for filterNot not dropWhile.

Tim
  • 26,753
  • 2
  • 16
  • 29
  • Yeah you are right. Is there a way to modify this function so that the test case passes?. Surely, the authors mean it this way. – Kid Charlamagne May 25 '19 at 07:14
  • 1
    `filterNot` is different from `dropWhile` because you need to build a new list rather than just truncate the old one, so you need to re-write the function rather than just modify it. – Tim May 25 '19 at 07:22
  • Got it. I have misunderstood the question I guess. The function does exactly what it is supposed to do. – Kid Charlamagne May 25 '19 at 14:37