2011-12-27 15 views
0

次の例は、問題を単純化したものです。 私はリスト[Either Foo Bar]と別のリスト[Biz]を持っています。 考えられるのは、それぞれBiz要素を[Either Foo Bar]まで、[Either Foo Bar]の先頭からBizが空になるまで繰り返すことです。その結果、今の問題は、それが[Biz]で次の要素を使用する時が来た[Either Foo Bar]の初めに開始できることです[Either Foo Bar]このリストで正しく反復処理する方法

によりBar秒未満のFooのがあるだろうということになります。

私がやろうとしていることの例を投稿して、それが助けになるならば。

更新: 私が使用している実際のタイプはここにありますが、それでも外的な情報かもしれないと思うものは除外しています。私は私が何をしようとしている

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

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

重要な何かが[Either UnFlaggedDay CalendarDay]Left値に対してDayをチェックされて残っている場合は私に知らせてください。一致する場合は、次の変更を除いてまったく同じ新しいリストを作成します。UnFlaggedDayと、次の2つのUnflaggedDayCalendarDay. 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 

オーケーを持っているものだ、私はこだわっています場所です。次の3つの左の値を右の値に変更する必要があります。 dummyFunc'の私の意図は、最初のLeft値でリストを分割し、それを削除し、新しいRight値を追加し、以前に分割したリストに参加し、さらに2回繰り返すことでした。より良い方法がありますか?もしそうでなければ、私が言及した基準に基づいてリストを半分に分割する機能が既に存在するのでしょうか?私は手でそれをする方法を理解することができますが、私は車輪を再発明しようとはしていません。

+2

はい、例を投稿してください。 –

+0

はい、例が間違いなく助けになります。それがなければ、それは 'foldl iterateBizFooBarまたはFooBar bizList'でしょうか? –

答えて

2

私は[Biz]の各要素が離れて左(Foo)タイプから、右(Bar)タイプに[Either Foo Bar]の1つ以上の要素を調整するかもしれないとそれを取ります。これはちょうど倍です:

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が元eitherListと、その時点までのすべてのBizの要素を考慮した結果としてfuncに各呼び出しの間で渡されるかを見ることができます。ご覧のとおり、funcの実装は、これを便利にするものです。

+0

これをもっと見るほど、私は倍が私が望むものだと思います。 –

+0

マイケルのコメントを見ている人にとっては、私がポストした後約20秒間フォルダーになっていましたが、私はすぐに十分な編集をしてヒストリーを得ることができませんでした。 –

+0

ああ、ちょうどあなたの提案が正しい方向に私を動かしたと思うと言っていました。 –

関連する問題