【发布时间】:2021-01-19 23:57:26
【问题描述】:
我有一个工作(尽管效率低下)函数来检查 Python 中的数字是否为素数,我想将其转换为 Haskell。效率现在对我来说并不重要,因为我主要专注于在 Haskell 中制作一个使用初学者可以理解的语言功能的可读算法。
我是 Haskell 的新手,所以我可能对如何处理这个问题有错误的心态。我的基本算法是检查一个数字是否为奇数且大于 2,如果是,则检查它是否可以被任何数字整除,直到 2。
问题:我不知道如何设置i 等于[2..n] 范围内的递增项。
问题:有没有办法用一个变量遍历一个范围并引用它?
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(我目前拥有的):
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
【问题讨论】:
-
“我不知道如何设置 i 等于 [2..n] 范围内的递增项”您可以使用 lambda expression。跨度>
-
那么我会在每次 map 执行一次迭代时使用它来修改 i 吗?例如:[2..n]!!i where (\i -> i + 1)?
-
map (\i -> n `rem` i == 0) [2..n-1]将生成一个布尔值列表。and和or等一些函数可以使用该列表并生成单个布尔值。您可能还需要not。 (或者,使用库中的any或all。) -
@chi 或者可以使用 LC 和
null轻松清晰地重新实现。 :) -
在 Haskell 中,
and (some list)将只评估列表直到第一个 false。不要害怕产生明显尝试所有除数的布尔值的完整列表:Haskell 实际上不会尝试所有除数,而只会尝试and要求的数量。最终结果是,一旦找到第一个除数,您就退出“循环”。
标签: python haskell primes primality-test