【问题标题】:Scalaz unboxed tagged type not automatically unboxedScalaz 未装箱标记类型不会自动取消装箱
【发布时间】:2014-09-30 22:22:59
【问题描述】:

阅读http://eed3si9n.com/learning-scalaz/Tagged+type.html并试用示例代码:

import scalaz._; import Scalaz._

sealed trait KiloGram
def KiloGram[A](a: A): A @@ KiloGram = Tag[A, KiloGram](a)
val mass = KiloGram(20.0)
2 * mass

根据指南,应该产生40.0,但是,在 Scala 2.11.2 上我得到:

scala> 2 * mass
<console>:17: error: overloaded method value * with alternatives:
  (x: Double)Double <and>
  (x: Float)Float <and>
  (x: Long)Long <and>
  (x: Int)Int <and>
  (x: Char)Int <and>
  (x: Short)Int <and>
  (x: Byte)Int
 cannot be applied to (scalaz.@@[Double,KiloGram])
              2 * mass
                ^

2 * mass.asInstanceOf[Double]

工作得很好。

这是 2.10 与 2.11 的区别还是我遗漏了什么?如果我不能像这样(不再)使用它们并且不得不求助于显式强制转换,那么取消装箱的标记类型有什么意义?

【问题讨论】:

    标签: scala scalaz scalaz7 scala-2.11


    【解决方案1】:

    好的,原来这在 Scalaz 7.1 中被 https://github.com/scalaz/scalaz/pull/693 改变了。

    基本上,标记类型的旧实现被证明不够安全,因此在使用“标记”的内容之前需要显式解包标记类型:

    scala> trait Kg
    scala> val Kg = Tag.of[Kg]
    scala> val mass = Kg(15.0)
    scala> 3 * Kg.unwrap(mass)
    res0: Double = 45.0
    

    感谢#scalaz 上的 S11001001、ceedubs、tpolecat 和 adelbertC 指出这一点。

    【讨论】:

    • 我刚刚发布了页面的更新版本 (eed3si9n.com/learning-scalaz/Tagged+type.html)。 js1972 给我发了一个 PR 来解决这个问题,但直到现在我才开始修复它。
    • 不应该是2 * Kilogram.unwrap(mass)吗?你目前有Tag.unwrap(mass)
    • 是的,这更有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    相关资源
    最近更新 更多