I have a working (albeit inefficient) function to check if a number is prime in Python and I'd like to convert it to Haskell. Efficiency doesn't matter to me right now as I am focusing primarily on making a readable algorithm in Haskell that uses language features a beginner would understand.
I'm new to Haskell so I may have the wrong mindset about how to approach this. My basic algorithm is to check if a number is odd and above 2 and if so, check if it's divisible by any number before until 2.
Problem: I don't know how to set i
equal to an increasing term in the range [2..n]
.
Question: Is there a way to iterate over a range with a variable and refer to it?
Python:
def is_prime(n):
if n < 2:
return False # by definition, numbers smaller than 2 are not prime
if n == 2: # edge case, 2 is the only even number that is prime
return True
if (n % 2) == 0:
return False # if even, n is not prime (except 2)
else:
for i in range(2,n): #iterate from 2 to the input(n)-1 (since range() is non-inclusive of stop param)
if (n % i == 0): #if n is divisible by a number that isn't 1 or itself...
return False # ...it isn't prime
return True
Haskell (What I have so far):
isPrimeInner :: Int -> Bool
isPrimeInner n = map (n `rem` i == 0) [2..n] where i
-- I don't know how to set i equal to an increasing term
-- in the range [2..n]
isPrime :: Int -> Bool
isPrime 2 = True -- edge case
isPrime n = if n < 2
then False
else if n `rem` 2 == 0
then False
else isPrimeInner n
Simplest done with List Comprehensions:
Here
i
is drawn from the range2 .. n-1
, i.e. it takes on the increasing values from2
ton-1
, one at a time.When it divides
n
evenly without a remainder, a()
value is produced as a member of the output list, which is then tested for being empty, withnull
. The code thus expresses the concept "there does not exist suchi
from2
ton-1
that dividesn
evenly".The
i <- [2..n-1]
part is known as a generator part of a list comprehension, andrem n i == 0
a test expression.Testing:
Thanks to Haskell's lazy evaluation, when given a composite argument
n
,isPrime
fails as soon as possible, with the smallest divisori
ofn
.