2011-11-10 36 views
2

我想要做這樣的事情如何從另一個列表構建列表,爲原始列表中的每個元素創建多個元素?

[(x, y, x+y) | (x,y) <- original] 

但當然,這將返回類似:

[(0, 0, 0), (0, 1, 1), (1, 1, 2)] 

我想是這樣的:

[0, 0, 0, 0, 1, 1, 1, 1, 2] 

我很新哈斯克爾,並不熟悉它的成語。我如何在Haskell中完成這項工作?

+2

在未來你可以使用[hoogle](http://www.haskell.org/hoogle/?hoogle=%3A%3A+%5B%5BInt%5D%5D+-%3E+%5BInt%5D )而不是構建你的(現在已刪除的)答案中的函數。 –

+0

@ ThomasM.DuBuisson:這真的很酷,謝謝! –

回答

7

首先,對類型的謾罵。您正在從名爲original的列表中抽取一對(x,y)。原始郵件必須是一對清單,original :: [(a,b)],例如[(1,6), (4,9)]。然後爲每個元素構造一個元組,從而爲元組列表創建一個元組列表。我猜測你從來不想要任何元組,但實際上是想讓列表中的某些元素被你的函數合併,並將結果連接到一個新列表中。

你可能會尋找concatMap功能:

> :t concatMap 
concatMap :: (a -> [b]) -> [a] -> [b] 
> concatMap (\x -> [x,x+1,x+7]) [1,2,3] 
[1,2,8,2,3,9,3,4,10] 

如果你真的想消費一次,然後兩個(或更多)的元素也有一些失落的細節,例如,如果你有一個做什麼奇數元素和天氣或不重複元素(所以你看到[1,2,3]作爲兩個輸入1,22,3)。

如果元素重複那麼這只是一個concatMapzip

> let ls = [1,2,3] in concatMap (\(x,y) -> [x,y,x+y]) (zip ls (drop 1 ls)) 
[1,2,3,2,3,5] 

但是,如果你想看到他們爲[1,2]和[3]那麼你最好寫你自己功能:

func [] = [] 
func [x] = [[x]] -- What do you want with the odd remaining element? 
func (x:y:rest) = [x,y,x+y] : func rest 

> concat (func [1,2,3]) 
[1,2,3,3] 
+1

另外它會很好地注意'zip'和'unzip'。 –

5

例如,您可以創建一個列表清單,然後使用concat將其平滑。

concat [[x, y, x+y] | (x, y) <- original] 
6

看起來你只是在做一個非確定性的選擇 - 只是列表解析而已!

[v | (x,y) <- original, v <- [x, y, x+y]] 
相關問題