【问题标题】:Why getOrElse would lose type inference in scalaz为什么 getOrElse 会在 scalaz 中丢失类型推断
【发布时间】:2014-10-10 06:17:44
【问题描述】:

当我在Scalaz中使用Either类型时,这是一个非常好的设计,但是getOrElse方法会丢失类型推断。

val either = ~3.right[String] | "123" // either: String

val either = 3.right[String] | "123" // either: Any

为什么 val 要么 = 3.right[String] | “123”不是指 Int,而是 Any 发生。

这是一个缺陷还是设计的一部分?

在此先感谢

【问题讨论】:

    标签: scala scalaz scalaz7


    【解决方案1】:

    3.right[String]\/-[String, Int] 类型 即你在右边有一个Int,在左边有一个String。但是,您还提供了一个 String 作为右侧的后备值。

    然后编译器查找StringInt 的最低公共超类型,恰好是Any

    请记住,类型参数将提供有关“缺失”方面的信息:如果您有right,它将标记left 的类型,反之亦然。

    在您说的第一种情况下:我有一个左 Int,我的右将是一个 String(这与作为右后备值传递的“123”一致)

    在后者中,您的意思是:我有一个右 Int,我的左将是一个 String,但您随后提供了一个 String 作为右。

    【讨论】:

      【解决方案2】:

      发生这种情况的原因是BB >: B|\/ 的定义中的类型约束。见https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/main/scala/scalaz/Either.scala#L202-L210

      sealed abstract class \/[+A, +B] {
      ...
        def getOrElse[BB >: B](x: => BB): BB = ...
      
        def |[BB >: B](x: => BB): BB = ...
      ...
      }
      

      BB >: B 表示BB 必须是B 的超类型。在您的示例中,BInt"123"String。正如@Gabriele Petronella 指出的那样,BB 被推断为IntString 的“最低通用超类型”,恰好是Any

      如果签名如下所示,您的示例将无法编译。

      sealed abstract class \/[+A, +B] {
      ...
        def getOrElse[B](x: => B): B = ...
      
        def |[B](x: => B): B = ...
      ...
      }
      

      鉴于上述定义,x: B,在您的示例中为 Int。 “123”不是Int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-20
        • 2011-03-19
        相关资源
        最近更新 更多