The following example is a simplification of the problem.
I have a list [Either Foo Bar],and another list [Biz].
The idea is that I iterate each Biz element through [Either Foo Bar] ,from the beginning of the [Either Foo Bar], until Biz is empty. The result will be that there will now be more Bars and less Foos in the [Either Foo Bar]
The problem is being able to start at the beginning of [Either Foo Bar] when it’s time to use the next element in [Biz].
I could post an example of what I am trying to do, if it will help.
Update:
Okay here are the actual types I am using, still trying to leave out what I think may be extraneous information. Please let me know if I have left out something important
[Either UnFlaggedDay CalendarDay]
[(CalFlag,Product, Day)]
data CalFlag = FirstPass | SecondPass | ThirdPass deriving (Enum,Eq,Show)
What I’m trying to do is check the Day against the Left value in [Either UnFlaggedDay CalendarDay]. When I get a match, I want make a new list, that is exactly the same excepting the following changes : I will change that UnFlaggedDay, plus the next two UnflaggedDays in the list to 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)` that was just checked against. Below is some broken code that is in between my different approaches to this problem.
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' [] _ = []
Update:
I’ve made some test code to work out my thoughts. Here’s what I have so far
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
Okay here is where I am stuck. I need to be able to change the next three Left values to Right values. My intent for dummyFunc' was to split the list at the first Left Value, remove it, add the new Right value, join the previously split lists, and repeat two more times. Is there a better way? If not, is there already a function that will split a list in half based on the criteria I mentioned? I can figure out how to do it by hand, but I’m not trying to reinvent the wheel.
I take it that each element in the
[Biz]might adjust one or more elements in the[Either Foo Bar]away from the left (Foo) type and to the right (Bar) type. This is just a fold:The above is untested, but you can see how the updated
eitherListis passed between each call tofuncas a result of considering the originaleitherListand allBizelements up to that point. As you can see, your implementation offuncis what will make this useful.