2014-01-23 20 views
2

這是我第二天學習哈斯克爾和我被一個問題困住了。 我試圖解決99 Haskell questions 問題第八題是寫一個名爲「壓縮」功能,它的工作原理是這樣的:哈斯克爾學習者關於過濾和摺疊的小問題

>compress "aaaabbbbccccddddd" 
"abcd" 
>compress [1,1,1,1,2,3,4,4,4,4] 
[1,2,3,4] 

和這裏就是我寫道:

compress :: (Eq a) => [a] -> [a] 
compress [] = [] 
compress x = filter ((head x) `notElem` (compress $ tail x)) x 

編譯器說:

無法比擬預期型a -> Bool' with actual type布爾」

compress,我試圖從頭到尾遞歸地拾取新的元素。 (如回溯也許??)

我的算法錯了嗎? 是否有另外一種更可讀的方法來實現算法? (如:在哪裏放圓括號?或$

有人可以幫我一下嗎? 非常感謝。

壓縮 '(X:XS)= X:壓縮'(dropWhile(== X)XS)


由於盧博米爾的幫助下,我通過糾正我的代碼

它工作!

並感謝大家,我感到寵壞了! 你們好客!

我會繼續學習Haskell!

+0

在發佈之前總是在重新編譯之前進行修改。你有一個錯字 –

+2

在問這裏之前,找到一個有良好前景的初學者是令人耳目一新的。繼續努力,你會學到很多東西。 –

+0

這是我在Stackoverflow的第一篇文章。每個人都非常慷慨地幫助我,真是太棒了!非常感謝 –

回答

4

該算法基本上是好的,但它不檢查。 filter的第一個參數應該是a -> Bool的函數 - 對於列表中的一個元素,它應該告訴你是否拋出它。你有什麼是一個Bool價值。

函數的第二部分可能更好地用不同的模式實現。這將允許您刪除headtail函數。

compress [] = [] 
compress (x:xs) = x : compress (filter (/= x) xs) 

該圖案結合x到列表的第一個元素和xs是列表的尾部。函數應包含x結果,並遞歸調用自己的篩選xs(將x從中刪除)。

編輯:此功能不會做問題的要求。應該只刪除連續的重複項。這可以通過使用dropWhile而不是filter來修復,並稍微修改謂詞函數。

2

檢查過濾器的簽名:

Prelude> :t filter 
filter :: (a -> Bool) -> [a] -> [a] 

注意,第一個參數必須是一個函數。現在檢查你的表達式的類型。

Prelude> :t notElem 
notElem :: Eq a => a -> [a] -> Bool 

因此,notElem a b將返回Bool類型的值。

注意:我認爲你可能誤解了問題陳述。 aaabbbaaa的預期產出是多少? 我認爲它應該是aba,因爲這個問題表述爲

排除列表中的元素連續重複。

(強調我的)。

+0

您的解釋是正確的。給出的例子是「壓縮」aaaabccaadeeee「'返回''abcade」'。 –

+0

是的,謝謝,我首先誤解了。 –

8

是否有替代方法來實現更易讀的 方法算法?

是的。

import Data.List 

compress :: Eq a => [a] -> [a] 
compress = map head . group 

map head . group基本上是\xs -> map head (group xs)group xs將創建一個列表,列表中的所有相等的連續元素在列表中組合在一起。然後map head將根據需要將這些列表中的head個丟棄。

+0

可能值得在sort中加以處理,以便處理輸入列表未排序的情況:'compress = map head。組。 sort'(類型保持不變,'sort'在'Data.List'中)編輯:剛纔看到練習只是希望我們只消除連續的重複(即不是全部重複)。所以忽略這個...(我沒有看到刪除按鈕...) – iceman