带 AnyVal 的幻影类型?
Phantom Type w/ AnyVal?
鉴于 中 Haskell 中的以下 Phantom Type 示例:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Distance a = Distance Double
deriving (Num, Show)
data Kilometer
data Mile
marathonDistance :: Distance Kilometer
marathonDistance = Distance 42.195
distanceKmToMiles :: Distance Kilometer -> Distance Mile
distanceKmToMiles (Distance km) = Distance (0.621371 * km)
marathonDistanceInMiles :: Distance Mile
marathonDistanceInMiles = distanceKmToMiles marathonDistance
我试图将其翻译成 Scala:
case class Distance[A](x: Double) extends AnyVal
case object Kilometer
case object Mile
def marathonDistance: Distance[Kilometer.type] = Distance[Kilometer.type](42.195)
def distanceKmToMiles(kilos: Distance[Kilometer.type]): Distance[Mile.type] =
Distance[Mile.type](kilos.x * 0.621371)
def marathonDistanceInMiles: Distance[Mile.type] = distanceKmToMiles( marathonDistance )
假设这个 Phantom Type 实现在 Scala 中有效,Distance
的这种用法是否会导致分配,即使用堆,而不是堆栈?
如果会分配,是什么原因?
照原样,您的代码不应导致 Distance
class 的任何分配,因为它不会 any of the things that would cause it:
- a value class is treated as another type.
- a value class is assigned to an array.
- doing runtime type tests, such as pattern matching.
它不把它们当作另一种类型,没有数组,也没有类型测试。
在这些示例中,Distance
的一个实例将被分配、装箱和拆箱:
类型测试:
def d(dist: Distance[Mile.type]): Double = dist match {
case Distance(x) if x > 0 => 1.0
case Distance(x) => x
}
被视为另一种类型(通用 A):
def identity[A](t: A): A = t
数组:
val dist = Distance[Meter.type](1.0)
val arr = Array[Distance[Meter.type]](dist)
有没有type参数也是一样
鉴于
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Distance a = Distance Double
deriving (Num, Show)
data Kilometer
data Mile
marathonDistance :: Distance Kilometer
marathonDistance = Distance 42.195
distanceKmToMiles :: Distance Kilometer -> Distance Mile
distanceKmToMiles (Distance km) = Distance (0.621371 * km)
marathonDistanceInMiles :: Distance Mile
marathonDistanceInMiles = distanceKmToMiles marathonDistance
我试图将其翻译成 Scala:
case class Distance[A](x: Double) extends AnyVal
case object Kilometer
case object Mile
def marathonDistance: Distance[Kilometer.type] = Distance[Kilometer.type](42.195)
def distanceKmToMiles(kilos: Distance[Kilometer.type]): Distance[Mile.type] =
Distance[Mile.type](kilos.x * 0.621371)
def marathonDistanceInMiles: Distance[Mile.type] = distanceKmToMiles( marathonDistance )
假设这个 Phantom Type 实现在 Scala 中有效,Distance
的这种用法是否会导致分配,即使用堆,而不是堆栈?
如果会分配,是什么原因?
照原样,您的代码不应导致 Distance
class 的任何分配,因为它不会 any of the things that would cause it:
- a value class is treated as another type.
- a value class is assigned to an array.
- doing runtime type tests, such as pattern matching.
它不把它们当作另一种类型,没有数组,也没有类型测试。
在这些示例中,Distance
的一个实例将被分配、装箱和拆箱:
类型测试:
def d(dist: Distance[Mile.type]): Double = dist match {
case Distance(x) if x > 0 => 1.0
case Distance(x) => x
}
被视为另一种类型(通用 A):
def identity[A](t: A): A = t
数组:
val dist = Distance[Meter.type](1.0)
val arr = Array[Distance[Meter.type]](dist)
有没有type参数也是一样