簡體   English   中英

使用文件夾的Haskell錯誤

[英]Haskell error using foldr

我是Haskell的新手,並嘗試了一些練習

我不明白錯誤產生的原因以及產生原因

split = foldr 
        (\x y -> y:x)
        [[]]

解釋器上的錯誤如下

    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `y'
    In the expression: y : x
    In the first argument of `foldr', namely `(\ x y -> y : x)'
Failed, modules loaded: none.

有人可以幫忙嗎? 提前致謝

文件夾類型為

foldr :: (a -> b -> b) -> b -> [a] -> b

所以在分裂

split = foldr (\x y -> y:x) [[]]

yy:x必須具有相同的類型,這對於任何xy都是不可能的,因為y:x在列表中始終比y更深一步。

我想你想做x:y嗎?

回憶文件foldr的類型: (a -> b -> b) -> b -> [a] -> b foldr (a -> b -> b) -> b -> [a] -> b 這表示foldr需要一個函數,該函數將列表的元素與最終結果類型的值組合在一起,從而產生結果類型的新值。

對於第一個參數,您給了foldr函數\\xy -> y:x ,其中x是列表元素, y是下一步的結果; 並且應用此lambda的結果應與y具有相同的類型。

但是(:)的類型是a -> [a] -> [a] -也就是說,它將單個元素附加到列表的開頭。 在表達式y:x ,您將采用某種“結果”類型,並將其用作用作結果的列表的元素。

因此,GHC嘗試推斷結果類型b與類型[b]相同,然后當然與類型[[b]][[[b]]] ...等等。 因此,它抱怨“無限類型”。

在我之前的帖子回答了您的問題,但是在您發表評論之后,我可以看到您想要一個按謂詞將列表分開的函數。

您可以使用模塊GHC.Exts中的groupWith :: Ord b =>(a-> b)-> [a]-> [[a]],並在您的模塊中為其提供類型為(a-> Bool)的函數例:

groupWith even [1,2,3,4,5,6] yields [[1,3,5],[2,4,6]]

另外,有些丑陋但可以實現所需的“外出”類型的東西是:

split::Eq a => (a -> Bool) -> [a] -> [[a]]
split f ls = (ls \\ rl):rl:[]
    where rl = filter f ls

但是,由於您提供的二進制函數,總是會將提供的列表分成兩個列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM