Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of scanLeft in Chapter 3.3 does not match behaviour of List #256

Open
Sorixelle opened this issue Nov 4, 2024 · 0 comments

Comments

@Sorixelle
Copy link

"Exercise: Stream Combinators" asks:

Implement [...] scanLeft on Stream. They have the same semantics as the same methods on List, [...]

The behaviour of Lists scanLeft is as follows:

scala> def increment(x: Int, y: Int): Int = x + y
def increment(x: Int, y: Int): Int

scala> List.fill(5)(1).scanLeft(0)(increment)
val res0: List[Int] = List(0, 1, 2, 3, 4, 5)

However, using the solution provided by the book for Stream gives the following result (using the book's prior definition of ones):

scala> def increment(x: Int, y: Int): Int = x + y
def increment(x: Int, y: Int): Int

scala> ones.scanLeft(0)(increment).take(6)
val res0: List[Int] = List(1, 2, 3, 4, 5, 6)

The difference being that while List's scanLeft includes the zero value in the resulting List as-is, Stream's does not, instead applying f to zero and self.head as the first element of the resulting Stream. An implementation of scanLeft for Stream that follows the one in List could instead look like:

def scanLeft[B](zero: B)(f: (B, A) => B): Stream[B] = {
  val self = this
  new Stream[B] {
    def head: B = zero
    def tail: Stream[B] = self.tail.scanLeft(f(zero, self.head))(f)
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant