Scala: Making implicit conversion A->B work for Option[A] -> Option[B]

前端 未结 5 966
一个人的身影
一个人的身影 2020-12-14 08:25

I\'m trying to write a function which re-uses the implicit conversions which I have for Object A -> Object B when they are wrapped in an Option in a generic way so that Opti

5条回答
  •  有刺的猬
    2020-12-14 08:51

    I improved @jseureth answer and added support for Traversable:

    trait Mappable[A, B, C[_]] {
      def apply(f: A => B): C[B]
    }
    
    package object app {
    
      implicit class OptionMappable[A, B, C[X] <: Option[X]](option: C[A]) extends Mappable[A, B, Option] {
        override def apply(f: A => B): Option[B] = option.map(f)
      }
    
      implicit class TraversableMappable[A, B, C[X] <: Traversable[X]](traversable: C[A])
        (implicit cbf: CanBuildFrom[C[A], B, C[B]]) extends Mappable[A, B, C] {
        override def apply(f: A => B): C[B] = {
          val builder = cbf(traversable)
          builder.sizeHint(traversable)
          builder ++= traversable.map(f)
          builder.result()
        }
      }
    
      implicit def liftConversion[C[_], A, B](x: C[A])
        (implicit f: A => B, m: C[A] => Mappable[A, B, C]): C[B] = m(x)(f)
    
    }
    

    Now you can implicitly convert options and traversables:

    implicit def f(i: Int): String = s"$i"
    
    val a: Option[String] = Some(1)
    val b: Seq[String] = Seq(1, 2, 3)
    

提交回复
热议问题