Scala:对于选项[A] – >选项[B]进行隐式转换A-> B工作
发布时间:2020-12-16 09:35:44 所属栏目:安全 来源:网络整理
导读:我正在尝试编写一个重用使用对象A的隐式转换的函数 – 对象B当它们以通用方式包装在Option中时,使得Option [A] – 选项[B]转换也可以。 我想到的是: implicit def fromOptionToOption[A,B](from: Option[A])(implicit conversion: (A) = B): Option[B] = f
我正在尝试编写一个重用使用对象A的隐式转换的函数 – >对象B当它们以通用方式包装在Option中时,使得Option [A] – >选项[B]转换也可以。
我想到的是: implicit def fromOptionToOption[A,B](from: Option[A])(implicit conversion: (A) => B): Option[B] = from.map(conversion(_)) 当我分配一个(..)一个值,但是当我分配一个选项val时,这可以工作;请参阅以下控制台输出: scala> trait T defined trait T scala> case class Foo(i: Int) extends T defined class Foo scala> case class Bar(i: Int) extends T defined class Bar scala> implicit def fromFooToBar(f: Foo):Bar = Bar(f.i) fromFooToBar: (f: Foo)Bar scala> implicit def fromBarToFoo(b: Bar):Foo = Foo(b.i) fromBarToFoo: (b: Bar)Foo scala> implicit def fromOptionToOption[A,B](from: Option[A])(implicit conversion: (A) => B): Option[B] = from.map(conversion(_)) fromOptionToOption: [A,B](from: Option[A])(implicit conversion: (A) => B)Option[B] scala> val foo: Option[Foo] = Some(Bar(1)) foo: Option[Foo] = Some(Foo(1)) // THIS WORKS as expected scala> val fooOpt = Some(Foo(4)) fooOpt: Some[Foo] = Some(Foo(4)) scala> val barOpt2: Option[Bar] = fooOpt <console>:16: error: type mismatch; found : Some[Foo] required: Option[Bar] val barOpt2: Option[Bar] = fooOpt ^ //THIS FAILS. 我没有真正看到第一次和第二次转换之间的区别。不知怎的,它不会在后者中调用隐式转换。我想这与系统类型有关,但是我看不清楚。有任何想法吗? 解决方法
这里的线索:
scala> val fooOpt: Option[Bar] = Option(Foo(1)) fooOpt: Option[Bar] = Some(Bar(1)) 另一个: scala> implicit def foobar(x: String): Int = augmentString(x).toInt foobar: (x: String)Int scala> val y: Option[String] = Option(1) y: Option[String] = Some(1) scala> val y: Option[Int] = Option("1") y: Option[Int] = Some(1) 看起来像一个合法的奇怪的bug。我会弹出一个较小的测试用例并打开一个问题(或在JIRA中搜索一个)。 除了: 您可以使用一些类别理论来处理大量不同类型的“Option-ish”事物。 package object fun { trait Functor[Container[_]] { def fmap[A,B](x: Container[A],f: A => B): Container[B] } object Functor { implicit object optionFunctor extends Functor[Option] { override def fmap[A,B](x: Option[A],f: A => B): Option[B] = x map f } // Note: With some CanBuildFrom magic,we can support Traversables here. } implicit def liftConversion[F[_],A,B](x: F[A])(implicit f: A => B,functor: Functor[F]): F[B] = functor.fmap(x,f) } 这是一个更高级的,因为你将一些类别理论FP映射到问题上,但它是一个更通用的解决方案,根据需要将隐藏的会话提升到容器中。请注意,如何使用一个隐含的会话方法进行链接,该方法采用更有限的隐含参数。 此外,这应该使示例工作: scala> val tmp = Option(Foo(1)) tmp: Option[Foo] = Some(Foo(1)) scala> val y: Option[Bar] = tmp y: Option[Bar] = Some(Bar(1)) 并使你的使用有些更危险: scala> val tmp = Some(Foo(1)) tmp: Some[Foo] = Some(Foo(1)) scala> val y: Option[Bar] = tmp <console>:25: error: could not find implicit value for parameter functor: fun.Functor[Some] val y: Option[Bar] = tmp ^ 这告诉你方差是至关重要的,并且与弊端相互作用。我的猜测是,你遇到了一个非常罕见的,可能很难修复可以避免使用其他技术的错误。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |