2011-02-10 259 views
2
findMult lst n = [x | x <- lst, x `mod` n == 0] 

primes num = 
    let n = [2..num] 
     x = ceiling (sqrt num) 
     nsqrt = [2..x] 
     not_prime = map (findMult n) nsqrt 
    in diff2 n (concat not_prime) 

有以下问题,当我尝试运行它哈斯克尔暧昧型

<interactive>:1:0: 
    Ambiguous type variable `t' in the constraints: 
     `RealFrac t' arising from a use of `primes' at <interactive>:1:0-8 
     `Floating t' arising from a use of `primes' at <interactive>:1:0-8 
     `Integral t' arising from a use of `primes' at <interactive>:1:0-8 
    Probable fix: add a type signature that fixes these type variable(s) 

我尝试使用fromIntegral,但我不认为我正确地使用,让我编译错误。请帮忙。

这样做的目的是查找所有素数直到num。

+0

我假设`num`应该是`Integral`? – delnan 2011-02-10 21:46:41

+2

试着告诉编译器什么类型,以便它不必猜测。提供您期望的类型签名,然后查看是否有错误消息。这里的问题在于你为了自己的目的而将要一般化,没有明确说明你想要什么。 – 2011-02-10 21:46:46

回答

4

当您在预期使用浮点值的情况下使用整数值时(或反之亦然),您会收到类似的错误消息。

在这种情况下,问题是你打电话sqrt,它采用浮点值作为参数,在num使编译器认为num是一个浮点值。但也可以使用num作为n的上限,这是一个整数值列表(因为它被用作参数findMult,它需要一个整数值列表)。

所以它在num呼叫fromIntegral调用sqrt,这样才:

x = ceiling (sqrt (fromIntegral num)) 
3

而不是采取平方根,你可以把所有的广场到了极限。

-- instead of 
{- x = ceiling (sqrt num) 
    nsqrt = [2..x] -} 
-- avoid sqrt 
nsqrt = takeWhile (\x -> (x-1)^2 < num) [2..] 
-- or even avoid multiplication altogether 
nsqrt = map fst . takeWhile ((< num) . snd) . zip [2..] $ scanl1 (+) [1,3..]