noh*_*wnd 5 type-safety dependent-type idris
我正在与Manning的Idris进行类型驱动开发.给出了一个示例,教导如何将函数限制为类型族中的给定类型.我们有Vehicle
一个使用类型PowerSource
要么是Pedal
或Petrol
,我们需要编写一个函数refill
是typechecks仅适用于使用汽油作为其powersource车辆.
下面的代码有效,但不保证重新填充a Car
会产生a Car
而不是a Bus
.如何更改refill
函数的签名以仅允许Car
在给定a Car
和生成Bus
时生成Bus
?
data PowerSource
= Pedal
| Petrol
data Vehicle : PowerSource -> Type
where
Bicycle : Vehicle Pedal
Car : (fuel : Nat) -> Vehicle Petrol
Bus : (fuel : Nat) -> Vehicle Petrol
refuel : Vehicle Petrol -> Nat -> Vehicle Petrol
refuel (Car fuel) x = Car (fuel + x)
refuel (Bus fuel) x = Bus (fuel + x)
Run Code Online (Sandbox Code Playgroud)
这可以通过引入新VehicleType
数据类型并添加一个更多参数来实现Vehicle
:
data VehicleType = BicycleT | CarT | BusT
data Vehicle : PowerSource -> VehicleType -> Type
where
Bicycle : Vehicle Pedal BicycleT
Car : (fuel : Nat) -> Vehicle Petrol CarT
Bus : (fuel : Nat) -> Vehicle Petrol BusT
Run Code Online (Sandbox Code Playgroud)
你应该以某种方式编码构造函数之间的类型差异.如果您想要更多类型安全性,则需要向类型添加更多信息.然后你可以用它来实现refuel
功能:
refuel : Vehicle Petrol t -> Nat -> Vehicle Petrol t
refuel (Car fuel) x = Car (fuel + x)
refuel (Bus fuel) x = Bus (fuel + x)
Run Code Online (Sandbox Code Playgroud)
更换
refuel (Car fuel) x = Car (fuel + x)
Run Code Online (Sandbox Code Playgroud)
同
refuel (Car fuel) x = Bus (fuel + x)
Run Code Online (Sandbox Code Playgroud)
导致下一个类型错误:
Type checking ./Fuel.idr
Fuel.idr:14:8:When checking right hand side of refuel with expected type
Vehicle Petrol CarT
Type mismatch between
Vehicle Petrol BusT (Type of Bus fuel)
and
Vehicle Petrol CarT (Expected type)
Specifically:
Type mismatch between
BusT
and
CarT
Run Code Online (Sandbox Code Playgroud)