路径依赖类型:Idris到Scala

时间:2016-02-13 20:41:17

标签: scala idris

我在Idris的Type-Driven Development with Idris写了一个例子给Scala:

Idris(取自TDD与Idris)

data PowerSource = Petrol | Pedal

data Vehicle : PowerSource -> Type where
           Bicycle : Vehicle Pedal
           Car : (fuel : Nat) -> Vehicle Petrol
           Bus : (fuel : Nat) -> Vehicle Petrol

refuel : Vehicle Petrol -> Vehicle Petrol
refuel (Car fuel) = Car 100
refuel (Bus fuel) = Bus 200

Scala的

scala> sealed trait PowerSource 
defined trait PowerSource

scala> case object Petrol extends PowerSource
defined object Petrol

scala> case object Pedal extends PowerSource
defined object Pedal

scala> sealed abstract class Vehicle {
     |   type A <: PowerSource
     | }
defined class Vehicle

scala> case object Bicycle extends Vehicle {
     |   type A = Pedal.type
     | }

scala> case class Bus(fuel: Int) extends Vehicle {
     |   type A = Petrol.type
     | }
defined class Bus

scala> case class Car(fuel: Int) extends Vehicle {
     |   type A = Petrol.type
     | }

但是,我在尝试实施refuel时遇到了麻烦:

scala> def refuel[P <: Petrol.type](vehicle: Vehicle {type A = P} ): Vehicle = vehicle match {
     |   case Car(_) => Car(100)
     |   case Bus(_) => Bus(100)
     | }
<console>:20: warning: unreachable code
         case Bus(_) => Bus(100)
                           ^
refuel: [P <: Petrol.type](vehicle: Vehicle{type A = P})Vehicle

scala> refuel(Car(100))
res6: Vehicle = Car(100)

scala> refuel(Bus(5))
res7: Vehicle = Bus(100)

scala> refuel(Bicycle)
<console>:22: error: inferred type arguments [Bicycle.A] do not conform to method refuel's type parameter bounds [P <: Petrol.type]
       refuel(Bicycle)
       ^
<console>:22: error: type mismatch;
 found   : Bicycle.type
 required: Vehicle{type A = P}
       refuel(Bicycle)
              ^

请批评/纠正我的方法,并帮助我在Scala中使用refuel

1 个答案:

答案 0 :(得分:2)

unreachable code警告似乎是虚假的:如果不是,你就可以强迫Bus强制Car(这是不健全的)并导致{ClassCastExeception 1}} ......似乎不可能。

虚假警告是一个scalac错误。 Scala问题跟踪器中存在相关错误,但这似乎是一个不同的变体......您应该报告它。