0

以下示例是对问题的简化。我有一个清单[Either Foo Bar],还有另一个清单[Biz]。这个想法是我从 的开头迭代每个Biz元素,直到为空。结果将是现在 s 越来越多,越来越少[Either Foo Bar][Either Foo Bar]BizBarFoo[Either Foo Bar]

问题是能够在开始[Either Foo Bar]使用[Biz].

如果有帮助,我可以发布一个我正在尝试做的事情的例子。

更新:好的,这是我正在使用的实际类型,仍然试图忽略我认为可能是无关信息的内容。如果我遗漏了重要的内容,请告诉我

[Either UnFlaggedDay CalendarDay] [(CalFlag,Product, Day)]

data CalFlag = FirstPass
              | SecondPass
              | ThirdPass
                 deriving (Enum,Eq,Show)

我要做的DayLeft检查[Either UnFlaggedDay CalendarDay]. 当我找到匹配项时,我想创建一个新列表,除了以下更改外UnFlaggedDay完全相同: Product, Day)` 刚刚检查过。下面是我解决此问题的不同方法之间的一些损坏的代码。UnflaggedDayCalendarDay. At that point, I want to use the newly built list, that has the same number of elements still, and theminus 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' [] _ = []

更新:

我制作了一些测试代码来解决我的想法。这是我到目前为止所拥有的

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值,加入先前拆分的列表,然后再重复两次。有没有更好的办法?如果没有,是否已经有一个函数可以根据我提到的标准将列表分成两半?我可以弄清楚如何手动完成,但我不想重新发明轮子。

4

1 回答 1

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将使这变得有用。

于 2011-12-27T22:11:35.883 回答