Как я могу правильно перебирать этот список

Следующий пример является упрощением задачи. У меня есть список [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 в списке на CalendarDays. 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, объединить ранее разделенные списки и повторить еще два раза. Есть ли способ лучше? Если нет, есть ли уже функция, которая разделит список пополам на основе упомянутых мною критериев? Я могу понять, как сделать это вручную, но я не пытаюсь изобретать велосипед.


person Michael Litchard    schedule 27.12.2011    source источник
comment
Да, пожалуйста, выложите пример.   -  person Fred Foo    schedule 28.12.2011
comment
Да, пример точно не помешал бы. Без него могло бы быть foldl iterateBizFooBar eitherFooBar bizList?   -  person Daniel Fischer    schedule 28.12.2011


Ответы (1)


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

person Thomas M. DuBuisson    schedule 27.12.2011
comment
Чем больше я смотрю на это, тем больше я думаю, что складка - это то, что я хочу. - person Michael Litchard; 28.12.2011
comment
Для тех из вас, кто просматривает комментарий Майкла: это была папка в течение примерно 20 секунд после того, как я нажал на сообщение, но я отредактировал достаточно быстро, чтобы он не попал в историю. - person Thomas M. DuBuisson; 28.12.2011
comment
Ах да, я только что сказал, что думаю, ваше предложение направило меня в правильном направлении. - person Michael Litchard; 28.12.2011