I've tried
exstension[A] (f: Iterator[Iterator[A]){
def mapInner[B](f: A => B): Iterator[Iterator[B]
but this loses type information since if I give it a list[list[Int]] I get back Iterator[Iterator[Int]
CodePudding user response:
How about this:
Welcome to Scala 3.2.0-RC2 (17.0.3.1, Java Java HotSpot(TM) 64-Bit Server VM). Type in expressions for evaluation. Or try :help.
scala> import collection.IterableOps
scala> extension[X, I[X] <: IterableOps[X, I, I[X]],
| Y, O[Y] <: IterableOps[Y, O, O[Y]]](cc: O[I[X]])
| def mapInner[Z](f: X => Z): O[I[Z]] = cc.map(_.map(f))
scala> List(List(1, 2), List(3, 4)).mapInner(_ * 3) val res0: List[List[Int]] = List(List(3, 6), List(9, 12))
scala> Seq(Set(1, 2), Set(3, 4)).mapInner(_ * 3) val res1: Seq[Set[Int]] = List(Set(3, 6), Set(9, 12))
CodePudding user response:
Try functors and friends:
trait Functor[F[_]]:
extension [A](fa: F[A]) def fmap[B](fmap: A => B): F[B]
object Functor:
given Functor[List] with
extension [A](fa: List[A]) def fmap[B](fmap: A => B): List[B] =
fa.map(fmap)
given [F[_], G[_]](using F: Functor[F], G: Functor[G]): Functor[[x] =>> F[G[x]]] with
extension [A](fa: F[G[A]]) def fmap[B](fmap: A => B): F[G[B]] =
F.fmap(fa)(ga => G.fmap(ga)(fmap))
import Functor.given
val xs = List(1, 2, 3, 4)
val xss = xs.map(x => List(x, x))
val fxss = summon[Functor[[x] =>> List[List[x]]]]
println(fxss.fmap(xss)((a: Int) => a * 2))
It's a lot of setup but likely you don't have to do it yourself and use a library like scalaz or cats where all these things are already defined.