Haskell 与n**0.5相关的类型变量错误不明确

Haskell 与n**0.5相关的类型变量错误不明确,haskell,Haskell,最终编辑: 我的最后一项职能是: isPrime n=n>1&&na->b,它允许您将任何Integral类型转换为任何Num类型,并且所有浮动的类型都是Num,因此您可以在sqrt中使用n: isPrime n = length [x | x <- take (round (sqrt (fromIntegral n))) primes, n `mod` x == 0] == 0 试试看:是的,我不知道为什么我要做取素数。我把我的素数函数和来自的函数混合在一起。那只是一个糟糕的想法。我编

最终编辑:

我的最后一项职能是:

isPrime n=n>1&&n<4
||n`mod`2/=0
&&n`mod`3/=0

&&长度[x | x让我们看看涉及tge的运算符的类型

(**) :: Floating a => a -> a -> a
mod :: Integral a => a -> a -> a
将这两个运算符应用于同一个变量
n
。但是,没有一个类型同时满足这两个约束,即使存在,Haskell也不知道如何选择一个

有两种方法可以解决这个问题。一种是说
从整数n**0.5
(或者,也许更好,使用
sqrt
)。可以找到另一种方法


最后但并非最不重要的一点是,你可能会注意到√素数列表中的n个元素不太合理。您需要小于的素数√n、 查看
takeWhile
函数。

问题是,
n**0.5
(或者简单地写为
sqrt n
)要求
n
是浮动的

(**) :: Floating a => a -> a -> a
sqrt :: Floating a => a -> a
但是
mod
要求
n
整数

mod :: Integral a => a -> a -> a
Haskell是一种没有隐式类型转换的语言,因此您不能将
Int
传递给
sqrt
。您可以在GHCi中尝试:

x = 4 :: Int
sqrt x -- error
为了解决这个冲突,您可以使用这样一个函数
fromIntegral::(Integral a,Num b)=>a->b
,它允许您将任何
Integral
类型转换为任何
Num
类型,并且所有
浮动的
类型都是
Num
,因此您可以在
sqrt
中使用
n

isPrime n = length [x | x <- take (round (sqrt (fromIntegral n))) primes, n `mod` x == 0] == 0

试试看:

是的,我不知道为什么我要做取素数。我把我的素数函数和来自的函数混合在一起。那只是一个糟糕的想法。我编辑代码使用
sqrt n
,我编辑代码使用
round(sqrt n)
这两种方法仍然会导致
浮点Int
的错误。你不能取整数的平方根。你看过fromIntegral吗?我刚刚编辑成了
四舍五入(sqrt(fromIntegral n))
多亏了你和Yuri,效果非常好。非常感谢你刚刚编辑成了
四舍五入(sqrt(fromIntegral n))
多亏了你和n.“代词”m,它工作得很好。非常感谢你为你添加了一行注释:
isPrime::Int->Bool
。有一些纯整数算法可以找到整数平方根的底。例如,请参阅。这样你就可以完全避免处理浮点数。
mod :: Integral a => a -> a -> a
x = 4 :: Int
sqrt x -- error
isPrime n = length [x | x <- take (round (sqrt (fromIntegral n))) primes, n `mod` x == 0] == 0
isPrime n = null [x | x <- take (round $ sqrt $ fromIntegral n) primes, n `mod` x == 0]