MyList - step 6
Use Scala’s for-comprehension with MyList. Because we implemented map and flatMap, MyList already supports for-comprehension. We’ll also add withFilter to support if guards inside for.
For-comprehension basics
A for-comprehension like this:
val result = for
a <- MyList(1, 2, 3)
b <- MyList(a, a + 1)
yield b
Is desugared by the compiler roughly into:
MyList(1, 2, 3).flatMap(a => MyList(a, a + 1).map(b => b))
Since we already implemented map and flatMap, this just works.
Try it out
@main
def main(): Unit =
val result = for
a <- MyList(1, 2, 3)
b <- MyList(a, a + 1)
yield b
println(result) // MyList(1, 2, 2, 3, 3, 4)
Filtering in for: withFilter
In for-comprehensions, if-guards (if a < 3) use withFilter under the hood (not filter). The standard library’s withFilter is lazy; we’ll keep it simple and make ours delegate to filter.
Add this to MyList:
trait MyList[A]:
...
def withFilter(p: A => Boolean): MyList[A]
Implementation
override def withFilter(p: A => Boolean): MyList[A] = filter(p)
Example
@main
def main(): Unit =
val result = for
a <- MyList(1, 2, 3, 4, 5) if a < 3
yield a
println(result) // MyList(1, 2)
Key ideas
- for-comprehension is syntax sugar that uses map, flatMap, and withFilter.
- Providing withFilter allows if-guards in for without changing our existing filter behavior.