gpt4 book ai didi

scala - 为什么Scala为涉及Either和值定义的 'Product'表达式选择类型 'for'

转载 作者:行者123 更新时间:2023-12-03 21:59:17 24 4
gpt4 key购买 nike

如果我使用 Option 值定义创建一个 for comprehension,它会按预期工作:

scala> for (a <- Some(4); b <- Some(5); val p = a * b) yield p
res0: Option[Int] = Some(20)

如果我没有值定义,则用Either 做同样的事情:
scala> for (a <- Right(4).right; b <- Right(5).right) yield a * b
res1: Either[Nothing,Int] = Right(20)

但是,如果我使用值定义,scala 似乎为 for comprehension 推断出错误的容器类型:
scala> for (a <- Right(4).right; b <- Right(5).right; val p = a * b) yield p
<console>:8: error: value map is not a member of Product with Serializable with Either[Nothing,(Int, Int)]
for (a <- Right(4).right; b <- Right(5).right; val p = a * b) yield p
^

它为什么这样做?有哪些方法可以解决这种行为?

最佳答案

问题来自val p = a*b如果你写的更简单

for (a <- Right(4).right; b <- Right(5).right) 产生 a*b

它编译,你得到正确的结果。

你的问题有两个原因

一、Either预测 mapflatMap没有通常的签名,即在通用类中定义的例程 map 和 flatMap M[A] , (A => B) => M[B](A => M[B]) => M[B] . M[A]例程在 Either[A,B].RightProjection 中定义,但在结果和论证中,我们有 Either[A,B]而不是投影。

二、方式val p = a*b在 for 理解中被翻译。 Scala 引用,6.19 p 90:

A generator p <- e followed by a value definition p′ = e′ is translated to the following generator of pairs of values, where x and x′ are fresh names:


(p,p′) <- for(x@p<-e) yield {val x′@p′ = e′; (x,x′)}

让我们稍微简化一下代码,去掉 a <- .另外, bp重命名为 ppp更接近重写规则,使用 ppp' . a应该在范围内
for(p <- Right(5).right; val pp = a*p) 产量 pp

按照规则,我们必须替换生成器+定义。那是什么, for()yield pp ,不变。
for((p, pp) <- for(x@p <- Right(5).right) yield{val xx@pp = a*p; (x,xx)}) yield pp

内部 for 被重写为一个简单的映射
for((p, pp) <- Right(5).right.map{case x@p => val xx@pp = a*p; (x,xx)}) yield pp

这是问题所在。 Right(5).right.map(...)类型为 Either[Nothing, (Int,Int)] ,不是 Either.RightProjection[Nothing, (Int,Int)]正如我们所愿。它在外部 for 中不起作用(它也转换为 map。在 map 上没有 Either 方法,它仅在投影上定义。

如果您仔细查看您的错误消息,即使它提到了 Product,它也会这么说。和 Serializable ,它说它是一个 Either[Nothing, (Int, Int)] ,并且没有在其上定义 map 。对 (Int, Int)直接来自重写规则。

当尊重正确的签名时,理解旨在很好地工作。用 Either 的伎俩投影(它也有它的优点),我们遇到了这个问题。

关于scala - 为什么Scala为涉及Either和值定义的 'Product'表达式选择类型 'for',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7289657/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com