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