以下示例是问题的简化。
我有一个列表[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
更改为{{1 s CalendarDay
[(CalFlag,Product,Day)] . 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
更新
我已经制作了一些测试代码来解决我的想法。这是我到目前为止所拥有的
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' [] _ = []
好的,这是我被困的地方。我需要能够将接下来的三个Left值更改为Right值。我对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
值,加入以前拆分的列表,然后再重复两次。有没有更好的办法?如果没有,是否已经有一个功能可以根据我提到的标准将列表分成两半?我可以弄清楚如何手工完成,但我不是要重新发明轮子。
答案 0 :(得分:2)
我认为[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
的实施将使其变得有用。