Недавно я услышал о неупакованных теговых типах в scala, и пока я пытался узнать, как именно это работает, я нашел это вопрос, указывающий на проблемы с реализацией в scalaz. Одним из последствий исправления стала необходимость явного развертывания помеченного типа:
def bmi(mass: Double @@ Kg, height: Double @@ M): Double =
Tag.unwrap(mass) / pow(Tag.unwrap(height), 2)
Затем я рассмотрел первоначальную идею, где я мог бы сделать что-то вроде:
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
trait Kilogram
trait Meter
type Kg = Double @@ Kilogram
type M = Double @@ Meter
def bmi(mass: Kg, height: M): Double = mass / pow(height, 2)
Итак, теперь мне интересно, связаны ли проблемы, обнаруженные ранее в scalaz, с его подходом, или простая реализация также может иметь проблемы со стиранием, массивами или varargs. Дело в том, что я все еще изучаю scala, поэтому мое понимание ее системы типов довольно ограничено, и я не мог понять это самостоятельно.