确定Vect n的均匀分数是否为5?

时间:2016-04-12 02:16:36

标签: idris

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一起使用?

1 个答案:

答案 0 :(得分:2)

这取决于你想要达到的目标。 foo : (n : Nat) -> Vect n Nat -> Nat表示您可以将Nat应用于fooVect 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