在编译时确定Nat是否可被5整除的函数

时间:2016-04-10 15:44:47

标签: idris

使用Cactus有用的answer,我尝试编写一个函数,给定Nat,如果Nat可被5整除,则返回onlyModBy5Helper : (n : Nat) -> (k : Nat ** k `mod` 5 = 0) -> Nat onlyModBy5Helper n k = n }。

onlyModBy5 : Nat
onlyModBy5 = onlyModBy5Helper 10 (10 ** Refl)

然后是主要功能:

When checking right hand side of onlyModBy5 with expected type
        Nat
When checking argument pf to constructor Builtins.MkDPair:
        Type mismatch between
                0 = 0 (Type of Refl)
        and
                (\k =>
                   Prelude.Nat.Nat implementation of Prelude.Interfaces.Integral, method mod k
                                                                                             5 =
                   0) 10 (Expected type)

        Specifically:
                Type mismatch between
                        0
                and
                        Prelude.Nat.Nat implementation of Prelude.Interfaces.Integral, method mod 10
                                                                                                  5

然而,由于编译时错误而失败:

services:
    redirectionListener:
          class: Front\EcommerceBundle\Listener\RedirectionListener
          arguments: ["@service_container","@session"]
          tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

我做错了什么?

1 个答案:

答案 0 :(得分:3)

这种情况有点奇怪:Integral Nat的实现是:

partial
Integral Nat where
  div = divNat
  mod = modNat

如果您在类型签名中使用modNat而不是mod,则可行。类型统一者仍然存在一些问题。我想它没有进一步解决,因为它认为实现是部分的而不是总的。

但是,onlyModBy5Helper并未正是您尝试实现的目标,因为onlyModBy5Helper 4 (10 ** Refl)会返回4nk依赖对不需要是相同的值。这个函数需要n : Natn的证明,可能就是你想要的:

onlyModBy5Helper : (n : Nat) -> n `modNat` 5 = 0 -> Nat
onlyModBy5Helper n prf = n

请注意,这类似于一个依赖对,你可以(但不应该,因为它添加了不必要的抽象),将函数写为:

onlyModBy5Helper : (n : Nat ** n `modNat` 5 = 0) -> Nat
onlyModBy5Helper pair = fst pair