Как правильно перебрать этот список? - PullRequest
0 голосов
/ 28 декабря 2011

Следующий пример упрощает задачу.У меня есть список [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)

Я пытаюсь проверить Day против значения Left в [Either UnFlaggedDay CalendarDay].Когда я получаю совпадение, я хочу создать новый список, который точно такой же, за исключением следующих изменений: я изменю UnFlaggedDay, плюс следующие два UnflaggedDay в списке на CalendarDay s . 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 (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

Хорошо, вот где я застрял.Мне нужно иметь возможность изменить следующие три значения слева на значения справа.Мое намерение для dummyFunc' состояло в том, чтобы разделить список по первому Left значению, удалить его, добавить новое значение Right, присоединиться к ранее разделенным спискам и повторить еще два раза.Есть ли способ лучше?Если нет, то есть ли уже функция, которая разделит список пополам на основе упомянутых мною критериев?Я могу понять, как это сделать вручную, но я не пытаюсь изобретать велосипед.

1 Ответ

2 голосов
/ 28 декабря 2011

Я предполагаю, что каждый элемент в [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 сделает это полезным.

...