문제

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:

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 

The above is untested, but you can see how the updated eitherList is passed between each call to func as a result of considering the original eitherList and all Biz elements up to that point. As you can see, your implementation of func is what will make this useful.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top