阅读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 vs 2.11还是我错过了什么?如果我不能像这样(不再)使用它们并且必须求助于显式转换,那么未装箱的标记类型有什么意义呢?
答案 0 :(得分:7)
好的,事实证明这在Scalaz 7.1中被https://github.com/scalaz/scalaz/pull/693更改了。
基本上,标记类型的旧实现证明不够安全,所以它是这样做的,以便在&#34;标记&#34;的内容之前显式地展开标记类型。可以用:
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指出这一点。