簡體   English   中英

在無限列表的列表上使用 foldr

[英]Using foldr on a list of infinite lists

我正在嘗試在 Haskell 中編寫一個函數,它執行以下操作:您輸入一個整數列表,對於這些整數,使用 map,有一個函數應用於它們,返回這些整數的無限列表。 然后,我想使用 union 將 foldr 應用於列表列表,以便結果將是列表中這些列表的並集。

現在的問題是,當我做例如采取​​ 10 'function' [1,2] 時,它會首先計算 1 的無限列表,並且因為它是一個無限列表,它永遠不會為 2 執行此操作。那么它僅返回輸入列表中第一個元素的這個無限列表的前 10 個元素,並對其應用並集,這只是同一個列表。

我的問題是:有沒有辦法同時為輸入列表中的所有元素創建無限列表,例如,當我使用 10 個“函數”[1,2] 時,它將返回前 10 個1 和 2 的無限列表並集的元素。(我不知道輸入列表中的元素數)

這是我的代碼,以使其更清楚:

pow :: Integer -> [Integer]
pow n = map (^n) [1, 2..]

function :: [Integer] -> [Integer]
function xs = foldr union [] (map pow xs)

union函數處理任意列表並刪除重復項,因此它必須首先完全評估其中一個參數,然后才能繼續處理另一個參數。

我認為您想明確引入列表已排序的假設,然后您可以編寫一個有效的函數來合並(如合並排序中的合並)輸入列表並計算聯合,而無需在之前評估其中一個列表其他。

我不知道庫中是否存在這樣的合並函數,但您可以很容易地自己定義它:

-- | Computes the union of two sorted lists
merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
  | x <= y    = x : merge (dropWhile (== x) xs) (dropWhile (== x) (y:ys))
  | otherwise = y : merge (x:xs) (dropWhile (== y) ys)

然后,您使用此新merge功能的原始折疊應按預期運行:

ghci> pow n = map (^n) [1..]
ghci> function xs = foldr merge [] (map pow xs)
ghci> take 10 (function [2,3])
[1,4,8,9,16,25,27,36,49,64]

如果您打算對輸入和輸出列表進行排序,請查看data-ordlist 如果您只想要所有元素但不關心順序,請嘗試concat . transpose concat . transpose

暫無
暫無

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

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