如何在此列表中正确迭代

时间:2011-12-27 21:07:47

标签: algorithm haskell purely-functional

以下示例是问题的简化。 我有一个列表[Either Foo Bar]和另一个列表[Biz]。 我的想法是,我从Biz的开头迭代每个[Either Foo Bar]元素到[Either Foo Bar],直到Biz为空。结果是,Bar

现在会有更多Foo秒而不是[Either Foo Bar]

问题是能够在[Either Foo Bar]时开始使用[Biz]中的下一个元素。

我可以发布一个我想要做的例子,如果有帮助的话。

更新: 好的,这里是我正在使用的实际类型,仍然试图忽略我认为可能是无关的信息。如果我遗漏了重要的内容,请告诉我

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

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

我要做的是检查DayLeft中的[Either UnFlaggedDay CalendarDay]值。当我得到一个匹配项时,我想创建一个新列表,除了以下更改之外完全相同:我会将UnFlaggedDay和列表中的下两个UnflaggedDay更改为{{1 s CalendarDay [(CalFlag,Product,Day)] . At that point, I want to use the newly built list, that has the same number of elements still, and the(CalFlag,Product,Day)`刚刚检查过。下面是我解决此问题的不同方法之间的一些破解代码。

minus the

更新

我已经制作了一些测试代码来解决我的想法。这是我到目前为止所拥有的

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' [] _ = []

好的,这是我被困的地方。我需要能够将接下来的三个Left值更改为Right值。我对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 的意图是将列表拆分为第一个dummyFunc'值,将其删除,添加新的Left值,加入以前拆分的列表,然后再重复两次。有没有更好的办法?如果没有,是否已经有一个功能可以根据我提到的标准将列表分成两半?我可以弄清楚如何手工完成,但我不是要重新发明轮子。

1 个答案:

答案 0 :(得分: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的实施将使其变得有用。