2011-12-27 106 views
0

下面的例子是問題的簡化。 我有一個列表[Either Foo Bar],另一份[Biz]。 的想法是,我每次迭代元素Biz通過[Either Foo Bar],從[Either Foo Bar]的開始,直到Biz是空的。其結果將是,有現在在[Either Foo Bar]我怎樣才能正確地迭代通過這個列表

的問題是能夠在[Either Foo Bar]開始的時候它的時間來使用下一個元素[Biz]開始更加Bar s以上且Foo秒。

我可以張貼的什麼,我試圖做的,如果它會幫助一個例子。

更新: 好的這裏是我正在使用的實際類型,仍然試圖忽略我認爲可能是無關的信息。請讓我知道,如果我已經離開了一些重要的東西

[Either UnFlaggedDay CalendarDay] [(CalFlag,Product, Day)]

data CalFlag = FirstPass 
       | SecondPass 
       | ThirdPass 
       deriving (Enum,Eq,Show) 

我試圖做的是檢查Day反對[Either UnFlaggedDay CalendarDay]Left值。當我比賽,我希望做一個新的列表,這是完全一樣的除外以下更改:我會改變UnFlaggedDay,加上未來兩個UnflaggedDay S IN列表中CalendarDay小號. At that point, I want to use the newly built list, that has the same number of elements still, and the [(CalFlag,產品,日) ] minus the(CalFlag,Product,Day)``剛剛被檢查。下面是我在解決這個問題的不同方法之間的一些破解代碼。

flagReserved :: [Either UnFlaggedDay CalendarDay] -> Handler 
                [Either UnFlaggedDay 
                  CalendarDay] 
flagReserved ((Left (MkUFD day)):rest) = do 
    reserved <- runDB $ selectList [TestQueue ==. Scheduled_Q, 
            TestStatus /<-. [Passed,Failed]] [] 

    case (L.null reserved) of 
    True -> do 
      processedDays <- ((Left $ MkUFD day) :) <$> flagReserved rest 
      return processedDays 

    False -> return $ 
      flagReserved' (map prepList ((Left (MkUFD day)):rest)) 
         (flagProductTuple reserved) 

flagReserved ((Right (MkCal day)):rest) = do 
    processedDays <- ((Right $ MkCal day):) <$> flagReserved rest 
    return processedDays 
flagReserved _ = return [] 

flagReserved' :: [Either (UnFlaggedDay) CalendarDay] -> 
       [(CalFlag,Product,Maybe C.Day)] -> 
       [Either UnFlaggedDay CalendarDay] 

flagReserved' ((Left (MkUFD day)):restD) 
       ((calFlag,firmware,Just startDate):restF) = 
    case (startDate == day || not (calFlag == FirstPass)) of 
     True | (calFlag == ThirdPass) -> 
        flagReserved' ((Right $ 
            conScheduled day firmware Reserved) : restD) restF 

      | otherwise -> 
       flagReserved (Right $ 
           consScheduled day firmware Reserved) : 
           flagReserved' restD 
              ((succ calFlag, 
                firmware, 
                Just startDate) : 
                restF) 
     False -> (Left (MkUFD day)) : flagReserved' restD ((calFlag, 
                  firmware, 
                  Just startDate) : restF) 




flagReserved' ((Right (MkCal (Left (MkAD (dayText,day))))):restD) 
       ((calFlag,firmware,Just startDate):restF) = 
     case (startDate == day || not (calFlag == FirstPass)) of 
       True | (calFlag == ThirdPass) -> 
         (Right $ consScheduled day firmware Reserved) : 
         flagReserved' restD restF 
        | otherwise -> 
         (Right $ consScheduled day firmware Reserved) : 
          flagReserved' restD ((succ calFlag, 
                firmware, 
                Just startDate):restF) 
       False -> 
       (Right (MkCal (Left (MkAD (dayText,day))))) : 
       flagReserved' restD ((calFlag,firmware,Just startDate) : 
             restF) 


flagReserved' ((Right (MkCal (Right unAvailable))):restD) 
       ((calFlag,firmware,startDate):restF) = 
       (Right $ 
       MkCal $ 
       Right unAvailable) : 
       flagReserved' restD ((calFlag,firmware,startDate) : restF) 

flagReserved' unprocessed [] = unprocessed 
flagReserved' [] _ = [] 

更新:

我做了一些測試代碼,以制定出我的想法。這裏是我到目前爲止

let reservedDays = [(FirstPass,IM,C.fromGregorian 2012 01 15), 
        (FirstPass,WAF,C.fromGregorian 2012 01 14), 
        (FirstPass,Backup,C.fromGregorian 2012 01 13) 
        ] 

dummyFunc :: [Either UnFlaggedDay CalendarDay] -> (CalFlag,Product,C.Day) 
    dummyFunc dayList (cFlag,product,day) = if day `elem` dayList 
             then dummyFunc' dayList (cFlag,product,day) 
             else dayList 

dummyFunc' dayList (cFlag,product,day) = 
    if (cFlag == ThirdPass) 
    then 

好了,這裏就是我卡住了。我需要能夠將接下來的三個Left值更改爲Right值。我對dummyFunc'意圖是在第一Left價值分裂列表,刪除它,添加新Right值,與之前分拆名單,然後重複兩次。有沒有更好的辦法?如果沒有,是否已經有一個函數根據我提到的標準將列表分成兩半?我可以弄清楚如何手工完成,但我並沒有試圖重新發明輪子。

+2

是的,請張貼示例。 – 2011-12-27 21:10:38

+0

是的,一個例子肯定會有所幫助。沒有它,它可能是'foldl iterateBizFooBar或者FooBar bizList'? – 2011-12-27 21:30:46

回答

2

我認爲在[Biz]每個元件可能調整在[Either Foo Bar]一個或多個元件遠離左邊(Foo)類型和向右(Bar)型。這只是一個方面:

eitherList = [Left(), Left(), Right 5, Right 9, Left()] 
bizList = [4,5,6,7,1] 

func eitherlst biz = if (Left()) `elem` eitherlst 
         then Right biz : delete (Left()) eitherlst 
         else eitherlst 

eitherList' = foldl func eitherList bizList 

以上是未經檢驗的,但你可以看到更新eitherList如何每次調用之間傳遞給func作爲考慮原eitherList和所有Biz元素到這一點的結果。正如你所看到的,你的func的實現將會使這個有用。

+0

我越看越這個,就越覺得foldl就是我想要的。 – 2011-12-28 01:18:53

+0

對於那些看着Michael評論的人來說 - 這是我在發佈後20秒左右的一篇文章,但我編輯得很快,以至於沒有獲得歷史記錄。 – 2011-12-28 01:25:31

+0

哦,是的,我只是說我認爲你的建議讓我朝着正確的方向前進。 – 2011-12-28 01:45:09