Floating
is a 类型类,不是构造函数或函数。您似乎确实已经发现您需要转换类型n
。正确的方法是使用fromIntegral
:
isPrime n = primeCheck n $ floor $ sqrt $ (fromIntegral n :: Double)
我们可以通过遵循函数的类型签名来了解为什么这是有效的。
从类型签名isPrime
, 我们看n
有类型Int
.
Since sqrt
期望一些Floating
类型(即作为类型类实例的类型Floating
),我们可以从Int
to a Double
using fromIntegral
。请注意,签名fromIntegral
is
(Integral a, Num b) => a -> b
Int
是一个实例Integral
(所以输入类型没问题)并且Double
是一个实例Num
所以输出类型没问题。
然后我们采取sqrt
得到一个新的Double
.
floor
需要一个类型为以下实例的参数RealFrac
. Double
恰好是两者的实例Floating
and RealFrac
,因此它将完成这项工作(无需转换)。floor
将把平方根转换回类型Int
.
请注意,由于输出类型为fromIntegral
是多态的,就像输入类型一样sqrt
and floor
,我们必须将转换类型指定为Double
,否则编译器不会知道which Num
/Floating
/RealFrac
要转换为的实例。您可能会看到错误ambiguous type 'a' in ...
.
您可以使用以下命令查看许多函数的类型签名Hoogle
EDIT
事实证明,显式类型签名fromIntegral
is not必需的。因此
isPrime n = primeCheck n $ floor $ sqrt $ fromIntegral n
就足够了。在我看来,只提供显式签名会更清楚,但在这种情况下没有必要。您可以阅读更多相关内容here.