You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证不符合预期的函数签名应用是不可能实现的?

函数签名负向验证的实现方法

这种针对函数签名的负向验证在支持依赖类型和命题否定的语言(如Idris、Agda、Coq)中完全可以实现,核心逻辑是利用命题否定的标准定义:Not P = P -> Void,即只要证明「不符合预期的情况成立会推导出荒谬(Void类型的值)」,即可完成负向验证。

以Idris为例的实现方案

你要验证的「长度为3的Nat向量和长度为2的Nat向量拼接,不可能得到长度为1的Nat向量」,可以直接用Idris原生的impossible关键字实现,代码如下:

import Data.Vect
import Data.Nat

-- 负向测试用例:若传入x ++ y = z的相等证明,可推导出荒谬
test_concat_invalid : (x : Vect 3 Nat) -> (y : Vect 2 Nat) -> (z : Vect 1 Nat) -> (x ++ y = z) -> Void
test_concat_invalid [] _ _ Refl impossible
test_concat_invalid (_::_) _ _ Refl impossible

上述代码中,Refl是Idris中命题相等的唯一构造子,当匹配到Refl时意味着编译器需要同时满足3 + 2 = 5和5 = 1,显然不可能,因此两个分支都被标记为impossible。只要这段代码能正常编译通过,就说明你需要的负向约束成立。

如果希望更贴近你给出的伪代码写法,也可以通过标准库的absurd函数简化写法,不用显式传入相等证明:

test_concat_invalid_simple : Vect 3 Nat -> Vect 2 Nat -> Vect 1 Nat -> Void
test_concat_invalid_simple x y z = absurd $ the (x ++ y = z) %search

其他场景说明

  • Agda中可以使用()荒谬模式标记不可能出现的模式分支,逻辑和Idris完全一致
  • Coq中可以通过inversion、contradiction等策略推导矛盾完成证明
  • 无依赖类型支持的普通静态类型语言(如Haskell、Rust)无法直接实现这类和值属性绑定的签名负向验证,只能通过运行时测试、类型级编程hack实现有限的校验效果

内容的提问来源于stack exchange,提问作者joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 18:36:04