Search code examples
scalascala-3

scala3 how to make generic zipWith extension method


I was trying to make a simple extension method zipWith that just maps a collection C[A] to C[(A, B)] like this:

List(1,2,3) zipWith (_ * 2)
// List((1,2), (2,4), (3,6))

I tried with this:

scala> extension[A, C[_] <: Iterable[_]] (s: C[A]) def zipWith[B](f: A => B): C[(A, B)] = s map ((x) => (x, f(x)))
-- Error:
1 |extension[A, C[_] <: Iterable[_]] (s: C[A]) def zipWith[B](f: A => B): C[(A, B)] = s map ((x) => (x, f(x)))
  |                                                                                                       ^
  |                                                       Found:    (x : Any)
  |                                                       Required: A

What am I missing with this?


Solution

  • You can use IterableOnceOps as explained here.

    import scala.collection.IterableOnceOps
    
    extension [A, CC[_]](it: IterableOnceOps[A, CC, Any])
      def zipWith[B](f: A => B): CC[(A, B)] =
        it.map(a => (a, f(a)))
    

    You can see the code running here.