Fil*_*uca 4 scala scalaz monoids
嗨,我正在研究高级Scala书,我在使用scalaz源代码中修改这段代码时遇到了一些麻烦:
object Tag {
/** `subst` specialized to `Id`.
*
* @todo According to Miles, @specialized doesn't help here. Maybe manually specialize.
*/
@inline def apply[@specialized A, T](a: A): A @@ T = a.asInstanceOf[A @@ T]
// ...
}
Run Code Online (Sandbox Code Playgroud)
它怎么样?a.asInstanceOf[A @@ T]不应该用ClassCastException失败吗?
使用的一个例子是:
Multiplication(2) |+| Multiplication(3)
Run Code Online (Sandbox Code Playgroud)
在这种情况下a是一个Int如何将它转换为@@[Int, Multiplication](Tagged[Int, Multiplication])
谢谢您的帮助.
Apo*_*isp 12
这是因为擦除.@@是一个纯粹的类型级构造,这意味着它没有运行时表示.
类型A @@ T是类型的别名AnyRef{type Tag = T; type Self = A}.并且因为Int可以安全地投射到AnyRef(在引擎盖下这是通过铸造java.lang.Integer到a java.lang.Object),这工作得很好.
附加结构{type Tag = T; type Self = A}仅在编译时存在,因此在JVM执行强制转换时已完全删除.
为什么这样?的目的@@(我发音"QUA")是创建一个新的类型从一个旧的,不造成运行时开销.
例如,如果我们使用,case class Multiplication(value: Int)这允许我们Multiplication视为不同Int,但它Multiplication在运行时创建一个实际的对象.
如果我们使用类型别名type Multiplication = Int,那么就没有运行时开销.但现在Multiplication与a无法区分Int,这不是我们想要的.
该类型Int @@ Multiplication阻止我们直接使用此类型的值Int,即使它实际上只是Int在运行时.
| 归档时间: |
|
| 查看次数: |
374 次 |
| 最近记录: |