加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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 2.9.1)

解决方法

这里的线索:

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
                            ^

这告诉你方差是至关重要的,并且与弊端相互作用。我的猜测是,你遇到了一个非常罕见的,可能很难修复可以避免使用其他技术的错误。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读