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]