4

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 のものですか、それとも何か不足していますか? このように (もう) 使用できず、明示的なキャストに頼らなければならない場合、ボックス化されていないタグ付きタイプのポイントは何ですか?

4

1 に答える 1

7

OK、これは 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 に感謝します。

于 2014-09-30T23:16:47.247 に答える