这个Haskell函数的类型签名是什么? [英] What is the type signature of this Haskell function?
问题描述
我写了一个函数来检查数字是否为素数:
素数n =素数'n 2(floor (sqrt n))
其中prime'ncu | n`mod` c == 0 = False
| c> u =真
|否则= prime'n(c + 1)u
我找不出什么类型签名这个功能应该是。起初,我认为它应该是这样的:
prime :: Integral a => a - > Bool
但编译时会出错,因为 sqrt
期望一个浮动a
和 floor 期望一个
RealFrac a
而不是积分a
。当我删除类型签名时,它会进行编译,但该函数不起作用:
* Euler> :t prime
prime ::(积分a,RealFrac a,Floating a)=> a - > Bool
* Euler>素数5
<互动>:1:0:
约束中含糊不清的类型变量't':
'使用'prime' < interactive>:1:0-6
在< interactive>使用'prime'时产生的'RealFrac t':1:0-6
'使用`prime'at< interactive>:1:0-6
可能的修复:添加修复这些类型变量的类型签名
我该如何使这个功能有效? 解决方案
问题是,在 n
上使用 sqrt
,这会强制 n
成为浮点数;你还可以在 n
上使用 mod
,这会强制n是一个整数。直观地看,从你的代码看, n
应该是一个整数,所以你不能直接调用 sqrt
code>就可以了。相反,您可以使用像 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 =真
|否则= prime'n(c + 1)u
I wrote a function to check whether a number is prime or not:
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
I can't figure out what the type signature of this function should be. At first I thought it should be this:
prime :: Integral a => a -> Bool
But then I get errors when compiling because sqrt
expects a Floating a
and floor
expects a RealFrac a
instead of an Integral a
. When I remove the type signature, it compiles, but the function does not work:
*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)
How can I make this function work?
The problem is that you use sqrt
on n
, which forces n
to be a floating-point number; and you also use mod
on n
, which forces n to be an integer. Intuitively, from looking at your code, n
should be an integer, so you can't directly call sqrt
on it. Instead, you can use something like fromIntegral
to convert it from an integer into another numeric type.
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
这篇关于这个Haskell函数的类型签名是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!