Scalaz 未装箱标记类型不会自动拆箱

标签 scala scalaz scalaz7 scala-2.11

阅读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 的事情还是我遗漏了什么?如果我不能像这样(不再)使用它们并且不得不求助于显式转换,那么未装箱的标记类型有什么意义?

最佳答案

好吧,原来这在 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 指出这一点。

关于Scalaz 未装箱标记类型不会自动拆箱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26131145/

相关文章:

scala - 使用状态 Monad 链接多个转换

mysql - Slick 3.0 (scala) 查询在运行多次之前不会返回数据(我认为)

scala - 玩!框架或类型安全堆栈

scala - Scala中 'HashSet'和 'Set'之间的区别?

scala - 将 Option[Validation[E, A]] 转换为 Validation[E, Option[A]]

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

logging - Scalaz 7 : Idiomatic way of turning values in Either to plain values plus logged errors?

scala - 如何使用 Akka Streams 在分隔符上拆分入站流

Scalaz 透镜组成

scala - 将双射提升为仿函数