2016-12-01 43 views
2

鑑於哈斯克爾以下幻影類型例如從phadej幻影類型w/AnyVal?

{-# 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 

我試圖把這種對斯卡拉:

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) 

假設這個幻影類型實現有效Scala中,將這種用法的Distance導致分配,即使用堆,而不是堆棧?

如果分配,原因是什麼?

回答

4

由於是,你的代碼應該不會導致Distance類的任何配置,因爲它不會做any of the things that would cause it

  1. 值類被視爲另一種類型。
  2. 一個值類被分配給一個數組。
  3. 進行運行時類型測試,如模式匹配。

它不把它們當作另一種類型,沒有數組,也沒有類型測試。

在這些實施例中,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) 

類型參數是否存在也是如此。