1

I'm struggling to translate my definition of the Sieve of Eratosthenes into Idris. Here is the function so far:

%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]

unfortunately, I'm getting a strange compiler error:

idris --build euler.ipkg
./E003.idr:18:18: error: expected: ")",
    dependent type signature
  else prime :: (eratos n (xs \\ [prime^2,prime^2+prime..n])) 

Why is the compiler looking for a type signature?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Langston
  • 1,083
  • 10
  • 26

1 Answers1

1

I was able to implement it as following:

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])

With this implementation, the type checker considers this function "covering".

Optimally, we wouldn't need the first case and could restrict the input to the case where the list is of length >= 1. However, it's hard to show the compiler either that the list will never be null or that this function's second argument is getting structurally smaller on each recursive call. If anyone has suggestions, please add them as comments or another answer!

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Langston
  • 1,083
  • 10
  • 26
  • Could you perhaps add some [Empirical Orders of Growth](http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth) data? Does Idris have "ordered list" type so `\\` would be efficient, with it? – Will Ness Oct 03 '16 at 17:42
  • @WillNess I don't really know how, you're welcome to compile my code and try. – Langston Oct 03 '16 at 19:32
  • it just entails measuring clock time for primes under e.g. 10,000 and under 20,000 (or any other pair, so the time is around 10 sec, say). I really don't want to install Idris just for this. – Will Ness Oct 04 '16 at 09:31