2015-12-28 66 views
1

我玩弄在Haskell有點熟悉它的列表元組的序列,但被困在以下問題:哈斯克爾算法在列表

我想定義,給定函數含有其他列表的一些量,每片含0或多個元組列表,創建一個新的列表如下:

*Main> foo 
    [ 
     [ (1,2), (3,4) ], 
     [ (5,6)   ], 
     [ (7,8), (9,10) ] 
    ] 


    = [ 
     [ (1,2), (5,6), (7,8) ], 
     [ (1,2), (5,6), (9,10) ], 
     [ (3,4), (5,6), (7,8) ], 
     [ (3,4), (5,6), (9,10) ] 
    ] 

因此,換句話說,函數應該與每一個元組從第一清單具有組合組成的列表在每種情況下,N個剩餘列表中的其他元組之一。

我正試圖爲此編寫一個遞歸算法,但無法將我的頭包裹在處理N個其他列表以組合元組。對於只有兩元組的名單,我會寫這樣的:

composeList [] _  = [] 
composeList (x:xs) list = composeTuples x list ++ composeList xs list 

composeTuples _ []  = [] 
composeTuples t (x:xs) = [t,x] : composeTuples t xs 

這給了我:

*Main Data.List> composeList [(1,2),(3,4)] [(5,6),(7,8)] 

    [ 
     [ (1,2), (5,6) ], 
     [ (1,2), (7,8) ], 
     [ (3,4), (5,6) ], 
     [ (3,4), (7,8) ] 
    ] 

雖然我似乎不能把拼在一起,並使其爲任意數量的工作列表,每個元組都有任何(> = 0)個元組。

我有興趣用Haskell的一些預定義函數(如果可能)解決這個問題,以及有點類似於上面例子中的方法。

在此先感謝!

回答

7

這只是列表monad,從每個列表中非確定性地選擇一個元素。

你從Control.Monad

λ. let as = [(1,2),(3,4)] 
λ. let bs = [(5,6)] 
λ. let cs = [(7,8),(9,10)] 
λ. let xss = [as, bs, cs] 
λ. sequence xss 
    [[(1,2),(5,6),(7,8)] 
    ,[(1,2),(5,6),(9,10)] 
    ,[(3,4),(5,6),(7,8)] 
    ,[(3,4),(5,6),(9,10)] 
    ] 
3

尋找的是sequence :: Monad m => [m a] -> m [a]的功能這裏有一個遞歸解決方案

solution :: [[a]] -> [[a]] 
solution (x: xs) = [y: ys | y <- x, ys <- solution xs] 
solution []  = [[]] 

解決方案背後的理念是:前置列表的頭部的每個元素到遞歸計算輸入列表尾部結果的每個列表。

+0

應該是'ys < - solution xs' – LeartS

+0

修好了,謝謝 –