【发布时间】:2012-10-08 14:19:15
【问题描述】:
由于Nat 的_+_ 操作通常在第一个参数中递归定义,因此类型检查器知道i + 0 == i 显然不是微不足道的。然而,当我在固定大小的向量上编写函数时,我经常遇到这个问题。
一个例子:我如何定义一个 Agda 函数
swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)
将第一个n 值放在向量的末尾?
因为在 Haskell 中一个简单的解决方案是
swap 0 xs = xs
swap n (x:xs) = swap (n-1) (xs ++ [x])
我在 Agda 中类似地尝试过这样的:
swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)
swap {_} {_} {zero} xs = xs
swap {_} {_} {suc i} (x :: xs) = swap {_} {_} {i} (xs ++ (x :: []))
但是类型检查器失败并显示消息(与上述swap-Definition 中的{zero}-case 相关):
.m != .m + zero of type Nat
when checking that the expression xs has type Vec .A (.m + zero)
那么,我的问题是:如何教 Agda,m == m + zero?以及如何在 Agda 中编写这样的swap 函数?
【问题讨论】:
-
对于它的价值,我不会在你的
swap签名中隐含自然(至少n),因为 Agda 无法推断它。 -
@copumpkin:我可能是错的,但我认为类型检查器在某些情况下可以推断出这两种情况(取决于使用
swap的上下文)? -
据我所知没有。假设你有一个
Vec Nat (5 + 3)。该添加将立即将类型减少到Vec Nat 8,然后 Agda 将尝试将其与Vec A (n + m)统一,然后举起双手(即,将您的术语设为黄色),因为它不能神奇地做减法。我有理由相信,即使使用 Agda 的奇特米勒模式统一,也不会有任何情况下它可以从上下文中推断出n和m。
标签: haskell functional-programming agda dependent-type