Тип Scalaz unboxed с тегами не распаковывается автоматически

Чтение 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 или я что-то упускаю? Какой смысл в неупакованных тэговых типах, если я не могу использовать их так (больше) и должен прибегать к явным приведениям типов?


person Erik Kaplun    schedule 30.09.2014    source источник


Ответы (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

Спасибо S11001001, ceedubs, tpolecat и adelbertC на #scalaz за указание на это.

person Erik Kaplun    schedule 30.09.2014
comment
Я только что опубликовал обновленную версию страницы (eed3si9n.com/learning-scalaz/Tagged+ type.html). js1972 прислал мне PR, чтобы исправить это, но до сих пор я не удосужился это исправить. - person Eugene Yokota; 02.10.2014
comment
Разве это не должно быть 2 * Kilogram.unwrap(mass)? У вас есть Tag.unwrap(mass) там в настоящее время. - person Erik Kaplun; 02.10.2014
comment
Да, это имеет больше смысла. - person Eugene Yokota; 02.10.2014