2009-11-30 135 views
2

RWH,第3章問題5請求的工作我創建了一個函數來測試paldindrome的存在。關於函數的Haskell問題

我寫了這一點,但它不工作

pCheck :: (Eq a) => [a] -> Bool; 
pCheck a = take n a == (take n $ reverse a) 
    where n = floor (length a/2) 

我得到這個錯誤,當我嘗試運行它:

No instance for (RealFrac Int) 
    arising from a use of `floor' at len.hs:13:11-32 
Possible fix: add an instance declaration for (RealFrac Int) 
In the expression: floor (length a/2) 
In the definition of `n': n = floor (length a/2) 
In the definition of `pCheck': 
    pCheck a = take n a == (take n $ reverse a) 
      where 
       n = floor (length a/2) 

我很困惑我究竟做錯了什麼?我知道一個paldindrome可以用a == reverse a進行測試,但現在我想以我的方式找到錯誤。

UPDATE:與代碼中的錯誤之一是固定的,通過司法建議,這個問題已經被更新,以反映剩下的問題

+0

一個簡單測試將是:'isPalindrome X =(秀X)==(反向$顯示X)' – 2009-11-30 06:37:13

+0

回覆:Jonno,我不認爲節目,或需要括號。 'isPalindrome = x ==反向x' – 2009-11-30 06:52:40

回答

5

表達

take n a == take n $ reverse a 

被解析爲

(take n a == take n) $ (reverse a) 

因爲$運營商優先0,甚至低於==運營要麼。

你需要表達:

take n a == (take n $ reverse a) 

此外,請尊重Haskell和使用length a而非length (a)。您還應該使用length a `div` 2而不是length a/2。函數div是整數除法,產生一個整數。

1

兩個問題。

首先,優先問題,通過司法注意:您需要(take n $ reverse a)take n (reverse a)

其次,你只能劃分有理數,不是整數,所以你真的想

where n = floor $ (toRational $ length $ reverse a)/2 

或者由法官表示 - 所以upvote他而不是我爲此 - 使用整數除div而不是(/),然後你不需要toRational

(這可能是可能的在這裏擺脫parens,但我不知道是否值得這個努力......)

0

當看到像length a/2這樣的表達式時,Haskell將不會在積分和浮點數之間進行任何類型的自動轉換。如果要分割2個Int類型的數字而忽略其餘的數字,請使用div

Prelude> 2 `div` 2 
1 
Prelude> 3 `div` 2 
1 
Prelude> 4 `div` 2 
2 
Prelude> 5 `div` 2 
2 
Prelude>