How to simplify nested map calls?

前端 未结 3 2069
独厮守ぢ
独厮守ぢ 2021-01-11 17:33

Suppose I have a few nested functors, e.g. List[Option[Int]] and need to call the map of the most inner one.

Now I am using nested m

3条回答
  •  佛祖请我去吃肉
    2021-01-11 17:47

    Yes, this is possible with scalaz.Functor:

    scala> import scalaz.Functor
    import scalaz.Functor
    
    scala> import scalaz.std.list._
    import scalaz.std.list._
    
    scala> import scalaz.std.option._
    import scalaz.std.option._
    
    scala> Functor[List].compose[Option].map(List(some(0), some(1)))(_ + 1)
    res1: List[Option[Int]] = List(Some(1), Some(2))
    

    However, this is longer than to simply call map with a nested map. If you often map nested structures, you can create helper functions:

    def map2[F[_], G[_], A, B](fg: F[G[A]])(f: A => B)
      (implicit F0: Functor[F], G0: Functor[G]): F[G[B]] =
      F0.map(fg)(g => G0.map(g)(f))
    
    def map3[F[_], G[_], H[_], A, B](fg: F[G[H[A]]])(f: A => B)
      (implicit F0: Functor[F], G0: Functor[G], H0: Functor[H]): F[G[H[B]]] =
      F0.map(fg)(g => G0.map(g)(h => H0.map(h)(f)))
    
    ...
    

    Usage:

    scala> map2(List(some(0), some(1)))(_ + 1)
    res3: List[Option[Int]] = List(Some(1), Some(2))
    
    scala> map3(List(some(some(0)), some(some(1))))(_ + 1)
    res4: List[Option[Option[Int]]] = List(Some(Some(1)), Some(Some(2)))
    

提交回复
热议问题