2013-06-18 87 views
0

我必須生成滿足一些要求的所有可能的數字列表。 我知道如何去固定尺寸的鏈條。 僞代碼:Haskell未知大小列表理解

[ [x1,x2,x3]| x1<-[1..5],x2<-[20..30], x2 `basedOn` x1, x3<-[100..110], x3 `basedOn` x1+x2] 

其中basedOn是一些布爾過濾器。

但如何做到這一點鏈的長度是在運行時確定的,又名變量?

我爲每個Xn生成了不同的集合。所以基本上我想要做的是爲X1,X2..Xn生成集合。然後,我想從X1挑選一個元素,並選擇從X2一個元素沒有與X1然後我想挑一個從X3X1X2碰撞等方面Xn colides。當我有一個結果。我希望它從Xn會議要求中挑選其他人。然後回到Xn-1再次選擇另一個有效的,然後再回到Xn並生成所有不再發生碰撞。然後我想回到更深層次等等。這是列表理解所做的事情,但我希望它具有動態大小。

我知道列表compehension是句法糖,所以動態生成它我可能不得不使用單子,但我不知道如何:) 你能幫我在Haskell如何實現這個嗎?

+0

遞歸的幫助。你可能看看http://stackoverflow.com/questions/9658409/haskell-combinations-and-permutation或http://stackoverflow.com/questions/8779765/combinations-of-a-list – phimuemue

回答

2

使用列表理解自身內部遞歸:

import Data.Maybe 

basedOn :: Int -> Int -> Bool 
basedOn a b = even (a+b) 

func :: [[Int]] -> [[Int]] 
func a = myFun a Nothing where 
    myFun :: [[Int]] -> Maybe Int -> [[Int]] 
    myFun [] _ = [[]] 
    myFun (xs:xss) j = [[a] ++ b | a <- xs, b <- myFun xss (next j a), pred j a] 
        where 
         pred Nothing _ = True 
         pred (Just x) a = a `basedOn` x 
         next Nothing a = Just a 
         next (Just x) a = Just (x+a) 

main = putStr $ show $ func [[1..5] , [6..10], [11..15]] 
+0

看起來像我什麼需要。我比j更懂得累加器,它爲baseOn集增加了更多元素。 pred是過濾功能,添加一個如果集合爲空或基於BasedOn過濾器之後。 – Machiaweliczny

+0

@ user2349668:的確如此 – Ankur