Idris 输入验证的命题与布尔值

Idris 输入验证的命题与布尔值,idris,Idris,我有以下代码: doSomething : (s : String) -> (not (s == "") = True) -> String doSomething s = ?doSomething validate : String -> String validate s = case (not (s == "")) of False => s True => doSomething

我有以下代码:

doSomething : (s : String) -> (not (s == "") = True) -> String
doSomething s = ?doSomething

validate : String -> String
validate s = case (not (s == ""))  of
                  False  => s
                  True => doSomething s 
检查输入是否为非空后,我希望将其传递给只接受验证输入(非空字符串)的函数

据我所知,验证是在运行时进行的 但是类型是在编译时计算的——这就是它不工作的方式。有什么解决办法吗

在玩代码时,我注意到:

:t (("la" == "") == True)
"la" == "" == True : Bool
但是


为什么类型不同?

这与运行时和编译时无关,因为您在
validate
中编写了两个分支,静态地处理空输入和非空输入情况;在运行时,您只需在两者之间进行选择

您的问题是:如果您有一个类型为
Bool
的值,那么这只是一个位,它可能会向任何方向移动。这就是
==
给你的

另一方面,
=
用于命题相等:类型(-as命题)
a=b
的唯一构造函数是
Refl:a=a
,因此通过对类型
a=b
的值进行模式匹配,您可以了解到
a
b
是真正相等的

通过将不相等作为命题传递给
doSomething
,我可以使您的示例起作用:

doSomething : (s : String) -> Not (s = "") -> String
doSomething "" wtf = void $ wtf Refl
doSomething s nonEmpty = ?doSomething

validate : String -> String
validate "" = ""
validate s = doSomething s nonEmpty
  where
    nonEmpty : Not (s = "")
    nonEmpty Refl impossible
据我所知,验证是在运行时进行的 但是类型是在编译时计算的——这就是它的方式 不起作用

那是不对的。它不起作用,因为

  • 我们需要
    with
    表单来执行依赖模式匹配,即。E根据从特定数据构造函数获得的信息对上下文执行替换和细化

  • 即使我们在这里将
    一起使用,
    not(s==”)
    在进行模式匹配时不在上下文中的任何位置,因此(在上下文中)没有什么可重写的,并且我们无法在稍后调用
    doSomething
    时演示
    not(s==”)=True的
    相等性

我们可以在这里使用包装器数据类型,它让我们保存一个证据,证明特定模式等于我们匹配的原始表达式:

doSomething : (s : String) -> (not (s == "") = True) -> String
doSomething s = ?doSomething

data Inspect : a -> Type where
  Match : {A : Type} -> {x : A} -> (y : A) -> x = y -> Inspect x

inspect : {A : Type} -> (x : A) -> Inspect x
inspect x = Match x Refl

validate : String -> String
validate s with (inspect (not (s == "")))
  | Match True  p = doSomething s p
  | Match False p = s

关于“布尔盲症”有两点:布尔人允许你欺骗平等,并“证明”两件事是平等的,即使它们不是,布尔人也会丢失信息。第一种说法很愚蠢:setoid也允许你欺骗平等,但每个人都对它们感到满意。一般来说,信息遗忘并没有错。在依赖类型的语言中,您始终可以恢复它。有时只需要删除一些类型级别的内容(比如异构相等或列表而不是向量)。这不是“布尔盲症”,而是“布尔闭眼”。你能解释一下当你进行模式匹配时,上下文中没有
not(s==”)
是什么意思吗?@dfeuer如果我们在等式的左侧有一个类型提到
not(s==”)
(在OP的
validate
中),依赖模式匹配必须将其重写为
True
False
。如果上下文中没有类型依赖项,那么模式匹配就不会提供额外的信息。
doSomething : (s : String) -> (not (s == "") = True) -> String
doSomething s = ?doSomething

data Inspect : a -> Type where
  Match : {A : Type} -> {x : A} -> (y : A) -> x = y -> Inspect x

inspect : {A : Type} -> (x : A) -> Inspect x
inspect x = Match x Refl

validate : String -> String
validate s with (inspect (not (s == "")))
  | Match True  p = doSomething s p
  | Match False p = s