Scala trait 编译失败的原因是什么?
What is the reason this Scala trait fails to compile?
我正在 Phantom Types which is reproduced here and here 上查看此博客 post 中的代码。
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 trait 编译失败的原因是什么?
您可以将 test3 = createRocket |> addO2 |> launch
读作:
val intermediateValue = createRocket |> addO2
val test3 = intermediateValue |> launch
createRocket |> addO2
转换为 addO2(createRocket())
,其中 returns 是 Rocket[Fuel, HasO2]
类型的中间值。 intermediateValue |> launch
转换为 launch(intermediateValue)
。 launch
接受类型为 Rocket[Fueled, HasO2]
的参数;对 launch
的调用将无法编译,因为您传递给它的类型错误。
我正在 Phantom Types which is reproduced here and here 上查看此博客 post 中的代码。
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 trait 编译失败的原因是什么?
您可以将 test3 = createRocket |> addO2 |> launch
读作:
val intermediateValue = createRocket |> addO2
val test3 = intermediateValue |> launch
createRocket |> addO2
转换为 addO2(createRocket())
,其中 returns 是 Rocket[Fuel, HasO2]
类型的中间值。 intermediateValue |> launch
转换为 launch(intermediateValue)
。 launch
接受类型为 Rocket[Fueled, HasO2]
的参数;对 launch
的调用将无法编译,因为您传递给它的类型错误。