在条件语句分支中告诉依赖函数条件为真

时间:2015-03-07 11:53:31

标签: idris

我有一个带有类型签名(x, y : SomeType) -> (cond x y) = True -> SomeType的函数。当我在if-then-else / case / with语句中检查条件时,如何在相应的分支中传递函数,该条件为真?

1 个答案:

答案 0 :(得分:24)

您可以使用DecEq轻松实现这一目标:

add : (x, y : Nat) -> x + y < 10 = True -> Nat
add x y _ = x + y

main : IO ()
main =
  let x = S Z
  in let y = Z
  in case decEq (x + y < 10) True of
          Yes prf => print (add x y prf)
          No _ => putStrLn "x + y is not less than 10"

但你不应该。

使用布尔值(通过=So)可以告诉您某些事情是真的,但不是为什么为什么非常重要,如果你想要一起组合证据或将它们分开。想象一下,如果add调用了需要x + y < 20的函数 - 我们无法通过x + y < 10 = True我们的证明,因为Idris对操作一无所知,只是它是真的

相反,您应该使用包含为什么它的数据类型的数据类型编写上述内容。 LTE是一种用于低于比较的类型:

add : (x, y : Nat) -> LTE (x + y) 10 -> Nat
add x y _ = x + y

main : IO ()
main =
  let x = S Z
  in let y = Z
  in case isLTE (x + y) 10 of
          Yes prf => print (add x y prf)
          No _ => putStrLn "x + y is not less than 10"

现在,如果add调用了需要LTE (x + y) 20的函数,我们可以编写一个函数来扩展约束:

widen : a `LTE` b -> (c : Nat) -> a `LTE` (b + c)
widen LTEZero c = LTEZero
widen (LTESucc x) c = LTESucc (widen x c)

这不是我们可以轻易用布尔人做的事情。