2017-08-17 55 views
0

我是新來的Haskell和這裏就是我想要做的: enter image description here組連續的一致好評元素

到目前爲止,只有編譯器錯誤:

groupElems :: Eq a => [a] -> [[a]] 
groupElems [] = [] 
groupElems (x:xs) = 
    let (a,b) = span (<= x) xs 
    in a : (groupElems b) 

謝謝。

錯誤:

Could not deduce (Ord a) arising from a use of ‘<=’ 
from the context (Eq a) 
    bound by the type signature for groupElems :: Eq a => [a] -> [[a]] 
+0

請張貼您獲得錯誤。此外,不要簡單地停止「有編譯器錯誤」,而是顯示你認爲錯誤的含義是很好的。通常,編譯器旨在描述錯誤是什麼。 –

回答

8

編譯器說:

Could not deduce (Ord a) arising from a use of ‘<=’ 
from the context (Eq a) 
    bound by the type signature for groupElems :: Eq a => [a] -> [[a]] 

什麼Haskell編譯旨在要說的是,你用<= x OM你的代碼,但<=功能是Eq部分typeclass:如果我們問<=來自哪裏,我們得到:

Prelude> :i (<=) 
class Eq a => Ord a where 
    ... 
    (<=) :: a -> a -> Bool 
    ... 
    -- Defined in ‘GHC.Classes’ 
infix 4 <= 

所以我們可以通過使用Ord typeclass解決問題:這意味着元素是有序的。但根據你的例子,這是而不是你想要什麼。如果我們用Ord a類型的約束,如:

groupElems :: Ord a => [a] -> [[a]] 
groupElems [] = [] 
groupElems (x:xs) = 
    let (a,b) = span (<= x) xs 
    in a : (groupElems b)

的第二個問題是,我們*調用spanxs名單上。 xs尾部的名單。所以這意味着我們不會考慮頭腦。我們可以通過使用別名@改變這種和處理整個列表xa

groupElems :: Ord a => [a] -> [[a]] 
groupElems [] = [] 
groupElems [email protected](x:_) = 
    let (a,b) = span (<= x) xa 
    in a : (groupElems b)

我們將獲得:

GHci > groupElems [] 
[] 
GHci > groupElems [1,2] 
[[1],[2]] 
GHci > groupElems [1,2,2,2,4] 
[[1],[2,2,2],[4]] 
GHci > groupElems [1,2,3,2,4] 
[[1],[2],[3,2],[4]] 

注意最後一個測試用例是不正確的。這是因爲32都滿足<= 3謂詞。

如果你想按平等,你應該使用(==) :: Eq a => a -> a -> Bool功能:

groupElems :: Eq a => [a] -> [[a]] 
groupElems [] = [] 
groupElems [email protected](x:_) = 
    let (a,b) = span (== x) xa -- use == instead of <= 
    in a : (groupElems b)

然後產生:

GHci > groupElems [] 
[] 
GHci > groupElems [1,2] 
[[1],[2]] 
GHci > groupElems [1,2,2,2,4] 
[[1],[2,2,2],[4]] 
GHci > groupElems [1,2,3,2,4] 
[[1],[2],[3],[2],[4]] 
2

你都制約你的功能,使a必須Eq類的。但是,功能<=屬於Ord類型類別。嘗試改變功能註釋本:

groupElems :: Ord a => [a] -> [[a]] 
+0

謝謝,這讓我感動,但書的練習給了我這個簽名groupElems :: Eq a => [a] - > [[a]] – Oleg

+2

在那種情況下,爲什麼你想比較小於或等於-至?爲什麼不直接比較平等? –

3

編譯器說,a一定是因爲使用<=Ord類型類的實例。所以,你可以糾正你的代碼是:

groupElems :: Ord a => [a] -> [[a]] 

但是,如果你仍然需要使用Eq,您可以使用==代替<=和代碼將工作。

我也注意到,你的代碼版本在[1,2,2,3,3]上返回[1, [], [3]]的例子,因爲你通過了xs而不是整個列表。

groupElems :: Eq a => [a] -> [[a]] 
groupElems [] = [] 
groupElems [email protected](x:xs) = 
    let (a,b) = span (== x) all 
    in a : (groupElems b) 

順便說一句,有一個在Data.List模塊group函數,你會不正是實現

2

我想你正在尋找的是Data.List.group;

Prelude> Data.List.group [1,2,2,2,4] 
[[1],[2,2,2],[4]]