Cactus演示了如何解决我的问题:Helper Function to Determine if Nat `mod` 5 == 0。
他写道:
onlyModBy5 : (n : Nat) -> {auto prf : n `modNat` 5 = 0} -> Nat
onlyModBy5 n = n
然后,我尝试使用该功能将onlyModBy5
应用于Vect n Nat
的总和。
foo : (n : Nat) -> Vect n Nat -> Nat
foo n xs = onlyModBy5 $ sum xs
但我得到了这个编译时错误:
When checking right hand side of foo with expected type
Nat
When checking argument prf to function Main.onlyModBy5:
Can't find a value of type
Prelude.Nat.modNatNZ, mod' (foldrImpl (\meth =>
\meth =>
plus meth meth)
0
id
xs)
4
SIsNotZ
(foldrImpl (\meth =>
\meth =>
plus meth meth)
0
id
xs)
(foldrImpl (\meth =>
\meth =>
plus meth meth)
0
id
xs)
4 =
0
Holes: Main.foo
如何将上述onlyModBy5
功能与foo
一起使用?
答案 0 :(得分:2)
这取决于你想要达到的目标。 foo : (n : Nat) -> Vect n Nat -> Nat
表示您可以将Nat
应用于foo
,Vect
Nat
Vect
n
foo
}}和Nat
将返回(n : Nat)
。
首先,您不需要明确的foo : Vect n Nat -> Nat
参数。如果你只写n
,Idris会在内部将foo : {n : Nat} -> Vect n Nat -> Nat
变为隐式参数:Vect
。
在论证中没有关于sum
的元素,因此没有关于它的[1,2,2]
。您也可以[1,1]
申请prf : (sum [1,1])
,而后者没有`modNat`
5 == 0)
onlyModBy5
的证明,所以很明显你可以&#39 ; t将总和应用于bar : (xs : Vect n Nat) -> {auto prf : (sum xs) `modNat` 5 = 0} -> Nat
bar xs = onlyModBy5 (sum xs)
。
您可以像以前一样要求将此证明作为参数:
foo : Vect n Nat -> Maybe Nat
foo xs = foo' (sum xs)
where
foo' : Nat -> Maybe Nat
foo' k with (decEq (k `modNat` 5) 0)
| Yes prf = Just (onlyModBy5 k {prf})
| No _ = Nothing
或者让它根据总和决定:
decEq
Nat
决定两个值是否在命题上相等(在这种情况下,如果它们是相同的Yes
),并且返回(prf : n
并带有`modNat`
{{1 }} 5 = 0)
他们是平等的,或No
证明他们不相等。然后可以使用onlyModBy5
将此证明提供给{prf}
。这扩展到{prf=prf}
,它为隐式参数提供了Yes
的证明,因为它们都被命名为prf
。