使用Idris实现isLast

时间:2017-07-01 20:15:52

标签: idris

使用Idris观察类型驱动开发的练习9.2:

data Last : List a -> a -> Type where
  LastOne : Last [value] value
  LastCons : (prf : Last xs value) -> Last (x :: xs) value

Uninhabited (Last [] value) where
  uninhabited LastOne impossible
  uninhabited (LastCons _) impossible

notLast : Not (x = value) -> Last [x] value -> Void
notLast prf LastOne      impossible
notLast prf (LastCons _) impossible

isLast : DecEq a => (xs : List a) -> (value : a) -> Dec (Last xs value)
isLast []      value = No absurd
isLast (x::[]) value = case decEq x value of
                         Yes Refl  => Yes LastOne
                         No contra => No (notLast contra)
isLast (x::y::ys) value = ?rhs

我在notLast prf LastOne案例中遇到编译时错误:

*section1> :r
Type checking ./section1.idr
section1.idr:20:9:notLast prf LastOne is a valid case
Holes: Main.rhs, Main.notLast

为什么编译器认为它是一个有效的案例?

1 个答案:

答案 0 :(得分:4)

Idris无法看到Not (value = value)Void同构,因此您需要通过解释问题所在来帮助它:

notLast : Not (x = value) -> Last [x] value -> Void
notLast prf LastOne      = absurd (prf Refl)
notLast prf (LastCons _) impossible