Int -> Bool primeCheck n i | n == 2 = True -6ren">
gpt4 book ai didi

Haskell "No instance for"错误

转载 作者:行者123 更新时间:2023-12-03 13:20:35 24 4
gpt4 key购买 nike

我正在尝试编写一个函数来检查一个数字是否为素数。我写了这个:

primeCheck :: Int -> Int -> Bool
primeCheck n i
| n == 2 = True
| i == 1 = True
| n `mod` i == 0 = False
| otherwise = primeCheck n (i -1)

isPrime :: Int -> Bool
isPrime n = primeCheck n (floor (sqrt n))

我收到这些错误:

No instance for (RealFrac Int) arising from a use of floor'
Possible fix: add an instance declaration for (RealFrac Int)
In the second argument of
primeCheck', namely (floor (sqrt n))'
In the expression: primeCheck n (floor (sqrt n))
In an equation for
isPrime': isPrime n = primeCheck n (floor (sqrt n))

No instance for (Floating Int)
arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `floor', namely `(sqrt n)'
In the second argument of `primeCheck', namely `(floor (sqrt n))'
In the expression: primeCheck n (floor (sqrt n)) Failed, modules loaded: none.


当我将代码更改为此以希望解决问题时:
primeCheck :: Int -> Int -> Bool
primeCheck n i
| n == 2 = True
| i == 1 = True
| n `mod` i == 0 = False
| otherwise = primeCheck n (i -1)

isPrime :: Int -> Bool
isPrime n = primeCheck n (floor (RealFrac (sqrt (Floating n))))

我明白了:

Not in scope: data constructor `RealFrac'

Not in scope: data constructor `Floating'



我怎样才能解决这个问题?

最佳答案

Floating 是一个类型类,而不是构造函数或函数。您似乎已经发现您需要转换 n 的类型。正确的方法是使用 fromIntegral :

isPrime n = primeCheck n $ floor $ sqrt $ (fromIntegral n :: Double)

我们可以通过遵循函数的类型签名来了解为什么会这样。

isPrime 的类型签名,我们看到 n 的类型是 Int

由于 sqrt 需要一些 Floating 类型(即类型类 Floating 的实例类型),我们可以使用 IntDouble 转换为 fromIntegral 。注意 fromIntegral 的签名是
(Integral a, Num b) => a -> b
IntIntegral 的一个实例(所以输入类型没问题), DoubleNum 的一个实例,所以输出类型没问题。

然后我们使用 sqrt 来获得一个新的 Double
floor 需要一个类型为 RealFrac 实例的参数。 Double 恰好是 FloatingRealFrac 的实例,所以它会完成这项工作(不需要转换)。 floor 会将平方根转换回 Int 类型。

注意,由于 fromIntegral 的输出类型是多态的,就像 sqrtfloor 的输入类型一样,我们必须将转换的类型指定为 Double ,否则编译器将不知道要转换为哪个 Num/ Floating/ RealFrac 实例.您可能会看到错误 ambiguous type 'a' in ...

您可以使用 Hoogle 查看许多函数的类型签名

编辑

结果证明不需要 fromIntegral 的显式类型签名。因此
isPrime n = primeCheck n $ floor $ sqrt $ fromIntegral n

就足够了。在我看来,只提供显式签名会更清楚,但在这种情况下没有必要。您可以阅读有关它的更多信息 here

关于Haskell "No instance for"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21943114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com