Function to Determine if Nat is Divisible by 5 at Compile-Time

孤街浪徒 提交于 2019-12-02 07:23:50

问题


Using Cactus's helpful answer, I tried to write a function that, given a Nat, will return that Nat if it's divisible by 5.

onlyModBy5Helper : (n : Nat) -> (k : Nat ** k `mod` 5 = 0) -> Nat
onlyModBy5Helper n k = n

And then the primary function:

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

However, that failed with a compile-time error:

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

What am I doing wrong?


回答1:


This case it is a bit odd: the Integral implementation of Nat is:

partial
Integral Nat where
  div = divNat
  mod = modNat

And if you use modNat instead of mod in your type signature, it works. The type unifier is still having some issues. I guess it does not resolve further, because it sees the implementation as partial and not as total.

However, your onlyModBy5Helper isn't exactly doing what you try to achieve, as onlyModBy5Helper 4 (10 ** Refl) would return 4, as n and k of the dependent pair don't need to be the same value. This function, that takes a n : Nat and a proof for the n, is probably what you want:

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

Note that this resembles a dependent pair, and you could (but shouldn't, as it adds unneeded abstraction), write the function as:

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


来源:https://stackoverflow.com/questions/36531852/function-to-determine-if-nat-is-divisible-by-5-at-compile-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!