[英]Foldl operation on a list of lists in Haskell
我有一個列表,例如
[[1,2,3,5],[24,6,8,2],[2,4,5,6,8]]
目標是獲取所有列表中共有的元素列表。 我的方法是創建一個 function 輸出兩個列表中的公共元素
common :: (Foldable t, Eq a) => [a] -> t a -> [a]
common list1 list2 = [x | x<-list1, elem x list2]
並使用折疊操作對 [[a]] 的所有元素進行遞歸操作
main :: IO ()
main = do
--- get the number of lists
q <- readLn :: IO Int
--- get the lists and store in a list of lists
list_of_lists <- map (map (read::String->Int ) . words) <$> replicateM q getLine :: IO [[Int]]
--- process and print the output
putStrLn $ show $ foldl (common) list_of_lists
不幸的是,這不會編譯並給出錯誤
• Ambiguous type variable ‘t1’ arising from a use of ‘common’
prevents the constraint ‘(Foldable t1)’ from being solved.
Probable fix: use a type annotation to specify what ‘t1’ should be.
These potential instances exist:
instance Foldable (Either a) -- Defined in ‘Data.Foldable’
instance Foldable Maybe -- Defined in ‘Data.Foldable’
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’
...plus one other
...plus 26 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘foldl’, namely ‘(common)’
In the second argument of ‘($)’, namely ‘foldl (common) list_of_lists’
In the second argument of ‘($)’, namely
‘show $ foldl (common) list_of_lists’
我可以理解可能的解決方法在於如何定義 function common
,但似乎無法得到它,因為我對 Haskell 相對較新。
您應該使用foldl1
,或為累加器提供初始值。 foldl:: Foldable t => (b -> a -> b) -> b -> ta -> b
期望一個初始值作為b
類型的累加器。 使用foldl1:: Foldable t => (a -> a -> a) -> ta -> a
,它將第一個元素作為初始累加器:
import Control.Monad(replicateM)
main :: IO ()
main = do
q <- readLn :: IO Int
list_of_lists <- replicateM q (map read . words <$> getLine) :: IO [[Int]]
print (foldl1 common list_of_lists)
這給了我們:
Prelude Control.Monad> main
3
1 2 3 5
24 6 8 2
2 4 5 6 8
[2]
如果項目列表為空,上述 function 將出錯。 所以這里q
應該像@JosephSible 所說的那樣嚴格大於零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.