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

Idris中如何使用Vect.filter返回的依赖对进行计算?

如何处理Idris中Vect.filter返回的依赖对?

Vect的filter返回(p : Nat ** Vect p Integer)这种依赖对,本质是因为过滤后的向量长度无法在编译期确定,所以用依赖对把动态长度和对应长度的向量绑定起来,保证类型安全。要对其中的元素执行sum、map、filter等操作,核心是先提取出内部的Vect实例,再用普通的Vect操作函数处理,具体方法如下:

1. 计算sum:提取向量后直接调用sum

方式一:模式匹配拆分依赖对

用let绑定把依赖对拆分成长度和向量,再对向量调用sum:

let (len ** vec) = filter (< 3) (fromList [1,2,3,4])
in sum vec

执行后会得到结果3,和List的操作逻辑一致。

方式二:用snd直接投影向量

依赖对的第二个元素就是目标Vect,直接用snd提取后调用sum:

sum $ snd $ filter (< 3) (fromList [1,2,3,4])

Idris会自动推导类型,识别出snd返回的是符合sum参数要求的Vect类型。

2. 执行map操作:处理向量后可重新构造依赖对

如果需要保留长度和向量的绑定关系,处理后可以重新组装成依赖对:

-- 模式匹配后map,再构造新的依赖对
let (len ** vec) = filter (< 3) (fromList [1,2,3,4])
in (len ** map (*2) vec)

如果不需要保留依赖对结构,直接操作向量即可:

map (*2) $ snd $ filter (< 3) (fromList [1,2,3,4])

3. 再次执行filter:嵌套处理依赖对

第二次filter依然会返回新的依赖对(因为长度可能再次变化),可以嵌套模式匹配或者链式投影:

嵌套模式匹配(保留长度信息)

let (len1 ** vec1) = filter (< 3) (fromList [1,2,3,4])
    (len2 ** vec2) = filter (> 0) vec1
in sum vec2

链式投影(直接取最终向量)

sum $ snd $ filter (> 0) $ snd $ filter (< 3) (fromList [1,2,3,4])

简单来说,依赖对只是把“长度”和“向量”打包在一起了,操作时先拆包取出向量,剩下的就和处理普通Vect完全一样,必要时再把新的长度和向量重新打包即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:42:53