我写了一个函数来检查一个数字是否是质数:
prime n = prime' n 2 (floor (sqrt n))
where prime' n c u | n `mod` c == 0 = False
| c > u = True
| otherwise = prime' n (c+1) u
我无法弄清楚这个函数的类型签名应该是什么。一开始我以为应该是这样的:
prime :: Integral a => a -> Bool
但后来我在编译时遇到错误,因为sqrt
期望一个Floating a
and floor
期望一个RealFrac a
而不是Integral a
。当我删除类型签名时,它可以编译,但该函数不起作用:
*Euler> :t prime
prime :: (Integral a, RealFrac a, Floating a) => a -> Bool
*Euler> prime 5
<interactive>:1:0:
Ambiguous type variable `t' in the constraints:
`Floating t' arising from a use of `prime' at <interactive>:1:0-6
`RealFrac t' arising from a use of `prime' at <interactive>:1:0-6
`Integral t' arising from a use of `prime' at <interactive>:1:0-6
Probable fix: add a type signature that fixes these type variable(s)
我怎样才能让这个功能发挥作用?
问题是你使用sqrt
on n
,这迫使n
为浮点数;你也用mod
on n
,这强制 n 为整数。直观地看你的代码,n
should是一个整数,所以不能直接调用sqrt
在上面。相反,你可以使用类似的东西fromIntegral
将其从整数转换为另一种数字类型。
prime :: (Integral a) => a -> Bool
prime n = prime' n 2 (floor (sqrt (fromIntegral n)))
where prime' n c u | n `mod` c == 0 = False
| c > u = True
| otherwise = prime' n (c+1) u
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)