所以我正在研究问题31.
我写了以下函数,希望确定一个数字是否为素数:
isPrime :: Integer -> Bool
isPrime x = prime x 2
where
prime :: Integer -> Integer -> Bool
prime x y | ((y*y) < x) and ((x `mod` y) /= 0) = prime x (y+1)
| ((y*y) >= x) = True
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
我的逻辑是创建一个isPrime函数,并在isPrime调用prime中存储一个函数来存储2个参数,我要检查的数字是否为prime(x)和迭代器来检查x的sqrt以下的所有数字并查看它们是否分开x.prime有3名警卫:
| ((y*y) < x) and ((x `mod` y) == 0) = prime x (y+1)
Run Code Online (Sandbox Code Playgroud)
这一行应该说:我传递的数字是否小于x(((y*y) < x))的平方根,如果检查是否x可被y(((xmod y) /= 0))整除,如果不是,我使用递归并递增y再次检查更高的数字.
这一行:
| ((y*y) >= x) = True
Run Code Online (Sandbox Code Playgroud)
应该是这样,如果平方根下面的所有数字都不分x,x必须是素数.
最后,这一行:
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
意味着沿线的某个数字除以数字x,因此它不是素数.
我认为我写的代码是有道理的,我知道它不是最有效的,考虑到我可以检查低于sqrt x的素数而不是所有低于sqrt x的数字,但无论如何,我对这个陈述有问题:
((y*y) < x)
Run Code Online (Sandbox Code Playgroud)
GHCi说:
The function `(y * y) < x' is applied to two arguments, but its type `Bool' has none
Run Code Online (Sandbox Code Playgroud)
我认为<应该接受两个参数并返回一个Bool,错误信息对我来说没有意义.你能帮我搞清楚我做错了什么吗?谢谢.
现在快速编辑我运行它,这一行:
| ((y*y) >= x) = True
Run Code Online (Sandbox Code Playgroud)
应该:
| ((y*y) > x) = True
Run Code Online (Sandbox Code Playgroud)
iva*_*anm 10
我认为你的意思是使用&&而不是and.完成后,它加载没有任何错误.
por*_*ges 10
要解释这里发生的事情......问题不在于<,它与整个表达方式有关:
((y*y) < x) and ((x `mod` y) /= 0)
Run Code Online (Sandbox Code Playgroud)
你缺少的是反击and:
((y*y) < x) `and` ((x `mod` y) /= 0)
Run Code Online (Sandbox Code Playgroud)
当你使用这样的函数中缀时,如果它不是一个运算符(即由符号组成++),那么你需要用反引号来包围它.
或者,您可以将非中缀用作函数,例如:
and ((y*y) < x) ((x `mod` y) /= 0)
Run Code Online (Sandbox Code Playgroud)
现在来解释错误信息.编译器所说的是你试图将表达式((y*y) < x)用作函数.由于Haskell中的函数应用程序不使用括号,所以类似f x y的函数f应用于两个参数x和y.
既然你忘了周围的反引号and,哈斯克尔解释((y*y) < x) and ((x `mod` y) /= 0)你尝试应用功能((y*y) < x)的参数and和((x `mod` y) /= 0).当然,这不起作用,因为((y*y) < x)返回Bool,这不是一个函数,所以它抱怨"函数(y * y) < x应用于两个参数,但它的类型Bool没有".Bool不是函数类型,因此它没有参数.
...
当然,你现在遇到的另一个错误是它应该&&不是and- and有类型[Bool] -> Bool.