-- | @spanEnd p l == reverse (span p (reverse l))@. The first list
-- returns actually comes after the second list (when you look at the
-- input list).
spanEnd :: (a -> Bool) -> [a] -> ([a], [a])
spanEnd p l = go l [] [] l
  where go yes _rev_yes rev_no [] = (yes, reverse rev_no)
        go yes rev_yes  rev_no (x:xs)
          | p x       = go yes (x : rev_yes) rev_no                  xs
          | otherwise = go xs  []            (x : rev_yes ++ rev_no) xs
spanEnd :: (a -> Bool) -> [a] -> ([a], [a])
spanEnd p l = go l [] [] l
  where go yes _rev_yes rev_no [] = (yes, reverse rev_no)
        go yes rev_yes  rev_no (x:xs)
          | p x       = go yes (x : rev_yes) rev_no                  xs
          | otherwise = go xs  []            (x : rev_yes ++ rev_no) xs
spanEnd p l = go l [] [] l
  where go yes _rev_yes rev_no [] = (yes, reverse rev_no)
        go yes rev_yes  rev_no (x:xs)
          | p x       = go yes (x : rev_yes) rev_no                  xs
          | otherwise = go xs  []            (x : rev_yes ++ rev_no) xs