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