我自己的Haskell函数中存在类型错误
我刚开始学习Haskell,在基本掌握了它的一些知识之后,我试着写一个简单的函数来测试一个数n的素性,这就是我想到的:我自己的Haskell函数中存在类型错误,haskell,Haskell,我刚开始学习Haskell,在基本掌握了它的一些知识之后,我试着写一个简单的函数来测试一个数n的素性,这就是我想到的: isPrime n i= 如果n
isPrime n i=
如果n<2
然后0
如果n==2 | | n==3,则为else
那么1
如果(n`mod`i)==0,则为else
然后0
否则,如果i==楼层(sqrt(n))
那么1
其他isPrime n(i+1)
该算法本身似乎是有效的(我用另一种语言测试了它),但是,当尝试调用任何数字时(即iPrime 5 2),我得到以下错误:
<interactive>:9:1:
Could not deduce (Floating a10) arising from a use of `isPrime'
from the context (Num a)
bound by the inferred type of it :: Num a => a
at <interactive>:9:1-11
The type variable `a10' is ambiguous
Note: there are several potential instances:
instance Floating Double -- Defined in `GHC.Float'
instance Floating Float -- Defined in `GHC.Float'
In the expression: isPrime 5 2
In an equation for `it': it = isPrime 5 2
<interactive>:9:9:
Could not deduce (Num a10) arising from the literal `5'
from the context (Num a)
bound by the inferred type of it :: Num a => a
at <interactive>:9:1-11
The type variable `a10' is ambiguous
Note: there are several potential instances:
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
instance Num Integer -- Defined in `GHC.Num'
instance Num Double -- Defined in `GHC.Float'
...plus three others
In the first argument of `isPrime', namely `5'
In the expression: isPrime 5 2
In an equation for `it': it = isPrime 5 2
但这只会返回一个不同的错误,甚至无法编译
编辑:以下是此版本的错误:
Prime.hs:10:48:
No instance for (RealFrac Integer) arising from a use of `floor'
In the second argument of `(==)', namely `floor (sqrt (n))'
In the expression: i == floor (sqrt (n))
In the expression:
if i == floor (sqrt (n)) then 1 else isPrime n (i + 1)
Prime.hs:10:54:
No instance for (Floating Integer) arising from a use of `sqrt'
In the first argument of `floor', namely `(sqrt (n))'
In the second argument of `(==)', namely `floor (sqrt (n))'
In the expression: i == floor (sqrt (n))
请帮助我,我应该如何更改代码以使其正常工作?提前感谢。不平等
i < sqrt n
这导致了一种解决方案,我们只检查通过sqrt n
的素数是否不除以n
primes :: [Integer]
primes = filter isPrime [1..]
isPrime :: Integer -> Bool
isPrime n = if n < 2
then False
else if n == 2 || n == 3
then True
else all (\i -> n `mod` i /= 0) . takeWhile (\i -> i*i <= n) $ primes
main = print $ take 10 primes
您应该尝试在ONCE中查找
sqrt
。添加类型注释的错误通常更深刻,应该指向实际问题。您应该将它添加到您的帖子中。@chi我明白了,所以sqrt实际上需要一个浮点型变量。但是如果我写isPrime::Double->Double->Double
,例如,mod
函数停止工作,因为它需要整数类型的数字。@MrTsjolder哇,我不知道这个存在,它非常有用!谢谢,这实际上解决了问题,尽管我仍然不明白如何使用sqrtI修复代码。我刚刚看到您的编辑,使用go
替换函数非常有用!另外,最初我是用Bool
编写的,只是为了调试而对其进行了更改。虽然效率低下,但计算非整数表达式的方法是from integral
:I==(floor$sqrt$from integral n)
@PeterDam我想说的是,平方根运算通常比平方一个整数要慢得多。。。但后来我在GHCi中进行了短暂的测试,实际上速度快了一点。。。甚至稍微使用Int
。只需在这里留下一点不可忽略的无关注意事项,如如果x那么True,否则..
,等等,都有点多余:)
i^2 < n
i*i < n
isPrime n i =
if n < 2
then 0
else if n == 2 || n == 3
then 1
else if (n `mod` i) == 0
then 0
else if i*i < n
then isPrime n (i + 1)
else 1
main = print $ isPrime 13 2
isPrime :: Integral a => a -> Bool
isPrime n = go n 2
where
go n i =
if n < 2
then False
else if n == 2 || n == 3
then True
else if (n `mod` i) == 0
then False
else if i*i < n
then go n (i + 1)
else True
main = print $ filter isPrime [1..30]
primes :: [Integer]
primes = filter isPrime [1..]
isPrime :: Integer -> Bool
isPrime n = if n < 2
then False
else if n == 2 || n == 3
then True
else all (\i -> n `mod` i /= 0) . takeWhile (\i -> i*i <= n) $ primes
main = print $ take 10 primes
primes :: [Integer]
primes = filter isPrime [1..]
isPrime :: Integer -> Bool
isPrime n = if n < 2
then False
else if n == 2 || n == 3
then True
else all (\i -> n `mod` i /= 0) . takeWhile (<= root_n) $ primes
where
root_n = floor . sqrt . fromIntegral $ n
main = print $ take 10 primes