这个Scala特性无法编译的原因是什么?

时间:2015-01-06 21:40:43

标签: scala traits

我正在查看Phantom Types上此博客文章中的代码,该帖子已转载herehere

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特性无法编译的原因是什么?

1 个答案:

答案 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的调用不会编译,因为您已将错误的类型传递给它。