这个演示了如何在Idris中编写函数来确定编译时是否Nat mod 5 = 0
:
onlyModBy5 : (n : Nat) -> {auto prf : n `modNat` 5 = 0} -> Nat
onlyModBy5 n = n
试验:
*Test> onlyModBy5 5
5 : Nat
*Test> onlyModBy5 10
10 : Nat
*Test> onlyModBy5 11
(input):1:12:When checking argument prf to function Main.onlyModBy5:
Can't find a value of type
1 = 0
如何在Scala中编写这样的函数(我假设使用shapeless
)?
答案 0 :(得分:2)
提供0为0 mod 5的证明(值),然后提供证明(N + 5)mod 5为0,证明N mod 5为0:
https://gist.github.com/stew/4074742#file-fizzbuzz-scala-L81-L90
答案 1 :(得分:2)
使用Shapeless非常简单。
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> import shapeless._
import shapeless._
scala> import ops.nat._
import ops.nat._
scala> type _5 = Succ[Succ[Succ[Succ[Succ[_0]]]]]
defined type alias _5
scala> def onlyModBy5(n: Nat)(implicit ev: Mod.Aux[n.N, _5, _0], toInt: ToInt[n.N]) = toInt()
onlyModBy5: (n: shapeless.Nat)(implicit ev: shapeless.ops.nat.Mod.Aux[n.N,_5,shapeless._0], implicit toInt: shapeless.ops.nat.ToInt[n.N])Int
scala> onlyModBy5(0)
res0: Int = 0
scala> onlyModBy5(25)
res1: Int = 25
scala> onlyModBy5(47)
<console>:20: error: could not find implicit value for parameter ev: shapeless.ops.nat.Mod.Aux[nat_$macro$6.N,_5,shapeless._0]
onlyModBy5(47)
^
整数被一些宏转换为Nat
,所以它们必须是文字,如果没有编译器爆炸就不能变得太大。 ToInt
类型类用于将Nat
转换回Int
。