[英]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) [[]]
y
和y:x
必須具有相同的類型,這對於任何x
和y
都是不可能的,因為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.