输入验证的命题与布尔值
Propositions vs. boolean values for input validation
我有以下代码:
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
但是
:t (("la" == "") = True)
"la" == "" = True : Type
为什么类型不同?
这与运行时与编译时无关,因为您在 validate
中编写了两个分支,它们静态地处理空输入和非空输入情况;在运行时,您只需在两者之间进行选择。
您的问题是 Boolean blindness:如果您有一个类型为 Bool
的值,那么,一个位可能会向任何方向移动。这就是 ==
给你的。
另一方面,=
用于命题相等:类型(-as-proposition)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
As far as I understand the validation is taking place during runtime
but the types are calculated during compile time - thats way it
doesn't work.
这是不正确的。它不起作用,因为
我们需要with
形式来执行依赖模式匹配,i。 e.根据从特定数据构造器获得的信息对上下文进行替换和细化。
即使我们在这里使用 with
,当我们进行模式匹配时,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
我有以下代码:
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
但是
:t (("la" == "") = True)
"la" == "" = True : Type
为什么类型不同?
这与运行时与编译时无关,因为您在 validate
中编写了两个分支,它们静态地处理空输入和非空输入情况;在运行时,您只需在两者之间进行选择。
您的问题是 Boolean blindness:如果您有一个类型为 Bool
的值,那么,一个位可能会向任何方向移动。这就是 ==
给你的。
=
用于命题相等:类型(-as-proposition)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
As far as I understand the validation is taking place during runtime but the types are calculated during compile time - thats way it doesn't work.
这是不正确的。它不起作用,因为
我们需要
with
形式来执行依赖模式匹配,i。 e.根据从特定数据构造器获得的信息对上下文进行替换和细化。即使我们在这里使用
with
,当我们进行模式匹配时,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