我正在查看Phantom Types上此博客文章中的代码,该帖子已转载here和here。
object RocketModule {
sealed trait NoFuel
sealed trait Fueled
sealed trait NoO2
sealed trait HasO2
final case class Rocket[Fuel, O2] private[RocketModule]()
def createRocket = Rocket[NoFuel, NoO2]()
def addFuel[O2](x : Rocket[NoFuel, O2]) = Rocket[Fueled, O2]()
def addO2[Fuel](x : Rocket[Fuel, NoO2]) = Rocket[Fuel, HasO2]()
def launch(x : Rocket[Fueled, HasO2]) = "blastoff"
implicit def toPiped[V] (value:V) = new {
def |>[R] (f : V => R) = f(value)
}
令我困惑的特殊方面是:
//This won't compile - there's no fuel
def test3 = createRocket |> addO2 |> launch
现在这段代码在编译时提出了额外的信息 - 而Scala的优点在于预先警告你。我的问题是:这个Scala特性无法编译的原因是什么?
答案 0 :(得分:2)
您可以将test3 = createRocket |> addO2 |> launch
视为:
val intermediateValue = createRocket |> addO2
val test3 = intermediateValue |> launch
createRocket |> addO2
转换为addO2(createRocket())
,返回类型为Rocket[Fuel, HasO2]
的中间值。 intermediateValue |> launch
转换为launch(intermediateValue)
。 launch
采用Rocket[Fueled, HasO2]
类型的参数;对launch
的调用不会编译,因为您已将错误的类型传递给它。