2012-05-03 52 views
1

我正在嘗試編寫一個remove函數,以便用戶可以輸入remove 'd' ["abc", "dc", "ad"]並獲得輸出["abc", "c", "a"]如何修復「發生檢查:無法構造無限類型」錯誤?

我的代碼是:

remove :: Eq a => a -> [[a]] -> [[a]] 
remove a (x:xs) = filter (not.a) (x:xs) 

,但我得到了以下錯誤消息:

Occurs check: cannot construct the infinite type: a = [a] -> Bool 
    When generalising the type(s) for `remove' 

什麼是錯誤訊息,我怎麼可以改變第二行,以便它的工作原理?

回答

5

您聲明參數a是支持相等的任何類型。

但是,您隨後在布爾表達式中使用它:not . a

not的類型是:: Bool -> Bool,所以a必須是Bool類型。但你已經說過不,它是Eq t => t

所以這是一個類型錯誤。

我想你的意思來過濾不等於a的所有元素,這將是:

remove a xs = filter (/= a) xs 

然而,你的輸入也是一個嵌套列表,所以你必須映射到內的元素過濾器:

remove a xs = map (filter (/= a)) xs 
+0

謝謝,你解釋得很好。 – user1351008

+0

他實際上是用'a'編寫的'not',它不會給出'Bool'類型,而是'[a] - > Bool'(一個列表,因爲它被用作列表列表上的過濾器謂詞)如錯誤消息所述。 –

6

類型的filter

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

因此您傳遞給filter的第一個參數必須是從列表的元素類型到Bool的函數。在

remove :: Eq a => a -> [[a]] -> [[a]] 
remove a (x:xs) = filter (not.a) (x:xs) 

你說

  1. a的類型爲a,並且該列表的類型是[[a]],即列表元素類型爲[a],並
  2. not . a,第一個參數filter,有鍵入[a] -> Bool

總之,這些意味着

a = [a] -> Bool 

但這是一個無限型。

你可能是指像filter (not . (a `elem`)),或等價filter (a `notElem`),如果filter意味着外部列表上的工作,或者如果你想從每個包含列表中刪除元素map (filter (/= a))

相關問題