2013-10-11 104 views
2

Haskell中的不同類型存在一些問題,我該如何解決這個問題?Haskell中的類型問題

無法比擬預期型Integer與實際類型Int -> t0 -> t0

感謝

isPrime :: Int -> Bool 
isPrime number 
    | (number == 1) || (number == 2) = True 
    | even number = False 
    | otherwise = checkDiv number (fromInteger (`sqrt` number)) 

checkDiv :: Int -> Int -> Bool 
checkDiv number divisor 
    | number == 2 = True 
    | (floor number `mod` divisor) == 0 = False 
    | otherwise = checkDiv number $ divisor - 1 
+1

你想解決這個問題? – bheklilr

+1

你爲什麼要把'sqrt'加入反引號?只需使用'(sqrt number)'。 –

+0

如果number是一個素數,isPrime數字應該爲真,如果不是則爲false,但我想使用這個算法 – msietrterc

回答

7

我已經想通了修改,以獲得代碼編譯,但它實際上並沒有找到素數。我不得不改變

fromInteger (`sqrt` number) 

floor $ sqrt $ fromIntegral number 

圍繞一個函數名的反引號標記是將其送到各種各樣的綴「經營者」,所以你可以做

mod x y 

x `mod` y 

但不是

`mod` x y 

接下來,您使用fromInteger代替fromIntegral,這是對Int S(IntInteger是不同的類型)的作品之一。最後,我從number中刪除floor,第二個後衛checkDiv,因爲number已經是Int

isPrime :: Int -> Bool 
isPrime number 
    | (number == 1) || (number == 2) = True 
    | even number = False 
    | otherwise = checkDiv number (floor $ sqrt $ fromIntegral number) 

checkDiv :: Int -> Int -> Bool 
checkDiv number divisor 
    | number == 2 = True 
    | (number `mod` divisor) == 0 = False 
    | otherwise = checkDiv number $ divisor - 1 

因此,讓我們通過您的代碼,以便您可以看到發生了什麼。如果我計算checkDiv 17 44floor $ sqrt $ fromIntegral 17),它會執行

checkDiv 17 4 
    | 17 == 2   No 
    | 17 `mod` 4 == 0 No 
    | otherwise = checkDiv 17 (4 - 1) = checkDiv 17 3 

checkDiv 17 3 
    | 17 == 2   No 
    | 17 `mod` 3 == 0 No 
    | otherwise = checkDiv 17 (3 - 1) = checkDiv 17 2 

checkDiv 17 2 
    | 17 == 2   No 
    | 17 `mod` 2 == 0 No 
    | otherwise = checkDiv 17 (2 - 1) = checkDiv 17 1 

checkDiv 17 1 
    | 17 == 2   No 
    | 17 `mod` 1 == 0 Yes = False 

17是黃金!你看到你的算法在做錯什麼嗎?

+0

非常感謝!應該是除數,而不是數字== 2. – msietrterc

+0

正確,這會使算法完成(除了考慮1是主數據,而不是大數)。我對你的下一個問題是你如何讓這個運行更快?你正在檢查2和'sqrt number'之間的單個數字,看看它是否是一個因素,但你已經過濾了所有的偶數。有沒有簡單的方法可以修改你的程序只檢查奇數除數? – bheklilr