簡體   English   中英

處理Haskell中的列表列表

[英]Working over a list of lists in Haskell

我是Haskell的初學者,所以我在使用嚴格類型的東西時會苦苦掙扎,只是想知道是否有人可以幫助我使用我正在嘗試構建的函數。 基本上,它需要一個列表列表,例如:

[[1,2,3], [7,6,8], [0,3,4]]

並將它們一起添加到一個列表中,通過沿着它的位置數來翻譯后面的列表。 因此,在示例列表上工作實際上將執行以下操作:

foldl (zipWith +) [] [[1,2,3],[0,7,6,8],[0,0,0,3,4]]

這是我當前的函數(獲取類型錯誤):

    addLists :: [[Integer]] -> [Integer]
    addLists [[]] = []
    addLists [[x]] = [x]
    addLists [x:xs] = zipWith (+) [x] ([0]++ (addLists xs))

請注意, ([0]++)(0:)相同,這將使它看起來更整潔,並為我們節省一兩納秒。 (我正在用納秒級的東西開玩笑 - 沒有人能分辨出什么東西的速度快一納秒,但無論如何它都更好。)

讓我們首先考慮制作您需要的列表。 我們想要

postponeLists [[1,2,3], [7,6,8], [10,20,30,40]] 
             = [[1,2,3], [0,7,6,8], [0,0,10,20,30,40]]
             = [1,2,3] : ones that should have zero in front of them

這是足夠的定義信息:

postponeLists [] = []
postponeLists (l:ls) = l : map (0:) (postponeLists ls)

現在你說

foldl (zipWith +) [] [[1,2,3],[0,7,6,8],[0,0,0,3,4]]

但你的意思是

foldl (zipWith (+)) [] [[1,2,3],[0,7,6,8],[0,0,0,3,4]]

但遺憾的是,這會給你[]因為zipWith任何列表用完元素, zipWith停止。 我們需要某種方式來壓縮它們並不會停止。

解決方案1:找到最長的一個,使用take maxlength.(++ repeat 0)將它們全部maxlength take maxlength.(++ repeat 0)
解決方案2:編寫另一個不停止的zipWith函數。

我更喜歡解決方案2.讓我們來看看zipWith定義

zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = [] -- here's the problem - it stops as soon as any list is empty

好吧,我們不要停下來:

zipWithMore :: (a -> a -> a) -> [a] -> [a] -> [a]
zipWithMore f (a:as) (b:bs) = f a b : zipWithMore f as bs
zipWithMore f []      bs      = bs -- if there's more in bs, use that
zipWithMore f as      []      = as -- if there's more in as, use that

現在你可以用zipWith (+)替換zipWithMore (+) 我會給你留下妙語。

我認為這樣做你想要的

import Data.List (transpose)

addLists :: Num a => [[a]] -> [a]
addLists xs = map sum . transpose $ zipWith (\n x -> replicate n 0 ++ x) [0..] xs

暫無
暫無

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

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