{- Combinator used to loop over @(nt1, nt2, mv2)@ triples. -}

processNt1Nt2Mv2 :: ASTAnalysis
                 -> [NtRoot]
                 -> (ASTAnalysis -> NtRoot -> NtRoot -> MvRoot -> M a)
                 -> M [[a]]
processNt1Nt2Mv2 aa nt1s f =
    sequence $
    do { nt2 <- filter (canBindOver aa (head nt1s)) (ntRoots aa)
       ; mv2 <- mvsOfNt aa nt2
       ; return $ sequence $ do { nt1 <- nt1s
                                ; return (local $ f aa nt1 nt2 mv2)
                                }
       }
processNt1Nt2Mv2 :: ASTAnalysis
                 -> [NtRoot]
                 -> (ASTAnalysis -> NtRoot -> NtRoot -> MvRoot -> M a)
                 -> M [[a]]
processNt1Nt2Mv2 aa nt1s f =
    sequence $
    do { nt2 <- filter (canBindOver aa (head nt1s)) (ntRoots aa)
       ; mv2 <- mvsOfNt aa nt2
       ; return $ sequence $ do { nt1 <- nt1s
                                ; return (local $ f aa nt1 nt2 mv2)
                                }
       }
processNt1Nt2Mv2 aa nt1s f =
    sequence $
    do { nt2 <- filter (canBindOver aa (head nt1s)) (ntRoots aa)
       ; mv2 <- mvsOfNt aa nt2
       ; return $ sequence $ do { nt1 <- nt1s
                                ; return (local $ f aa nt1 nt2 mv2)
                                }
       }