2011-12-27 147 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