使用Idris实施isLast:步步为营

时间:2019-05-14 14:02:59

标签: idris

我正在进行使用Idris进行类型驱动的开发中第9.1节中的练习2,但我不知道如何填补最后一个漏洞(请参见下面的notInTail

我已经阅读了Implementing isLast with Idris的答案,但是我被困在另一个地方。

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

notInNil : Last [] value -> Void
notInNil LastOne impossible
notInNil (LastCons _) impossible

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

notInTail : (notThere : Last xs value -> Void) -> Last (x :: xs) value -> Void
notInTail notThere LastOne = ?hole
notInTail notThere (LastCons prf) = notThere prf

isLast : DecEq a => (xs : List a) -> (value : a) -> Dec (Last xs value)
isLast [] value = No notInNil
isLast (x :: []) value = case decEq x value of
                              Yes Refl => Yes LastOne
                              No notHere => No (notLast notHere)
isLast (_ :: xs) value = case isLast xs value of
                              Yes prf => Yes (LastCons prf)
                              No notThere => No (notInTail notThere)

这是Idris的报告:

- + Main.hole [P]
 `--       phTy : Type
          value : phTy
       notThere : Last [] value -> Void
     -----------------------------------
      Main.hole : Void

1 个答案:

答案 0 :(得分:1)

我认为您不能证明notInTail是书面的,因为它不适用于空列表。但是,它确实适用于非空列表:

notInTail : (c : Last (y :: ys) value -> Void) -> Last (x :: (y :: ys)) value -> Void
notInTail c (LastCons prf) = c prf

isLast的第三种情况下,输入列表的尾部必须为非空,但您未指定。如果这样做,则可以应用notInTail

isLast (x :: (y :: xs)) value = case isLast (y :: xs) value of
                                     Yes prf => Yes (LastCons prf)
                                     No c => No (notInTail c)