簡體   English   中英

對 Haskell 中的列表進行折疊操作

[英]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.

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