我正努力将我对Eratosthenes筛子的定义翻译成伊德里斯。这是迄今为止的功能:
%default total
eratos : Nat -> (l : List Nat) -> { auto ok: NonEmpty l } -> List Nat
eratos limit (prime :: rest) =
if prime * prime > limit -- if we've passed the square root of n
then prime :: xs -- then we're done!
-- otherwise, subtract the multiples of that prime and recurse
else prime :: (eratos limit (rest \\ [prime^2,prime^2+prime..limit]))
main : IO ()
main = printLn $ eratos [2..100]
不幸的是,我收到了一个奇怪的编译器错误:
idris --build euler.ipkg
./E003.idr:18:18: error: expected: ")",
dependent type signature
else prime :: (eratos n (xs \\ [prime^2,prime^2+prime..n]))
为什么编译器要查找类型签名?
答案 0 :(得分:1)
我能够实现如下:
eratos : Nat -> (l : List Nat) -> List Nat
eratos _ [] = []
eratos limit (prime :: rest) =
if prime * prime > limit -- if we've passed the square root of n
then prime :: rest -- then we're done!
-- otherwise, subtract the multiples of that prime and recurse
else prime :: eratos limit (rest \\ [(prime*prime),(prime*prime+prime)..limit])
通过此实现,类型检查器会考虑此功能"覆盖"。
最理想的情况是,我们不需要第一种情况,并且可以将输入限制为列表长度为> = 1的情况。但是,很难向编译器显示该列表永远不会为null或者这个函数的第二个参数在每次递归调用时结构变小。如果有人有任何建议,请将其添加为评论或其他答案!