module List.Util where -- | The 'zipWithDefaults' function is like zipWith except that it -- continues until both lists are exhausted, filling in any missing -- elements with the given defaults. zipWithDefaults :: (a -> b -> c) -> a -> b -> [a] -> [b] -> [c] zipWithDefaults f x0 y0 [] [] = [] zipWithDefaults f x0 y0 xs [] = map (`f`y0) xs zipWithDefaults f x0 y0 [] ys = map (x0`f`) ys zipWithDefaults f x0 y0 (x:xs) (y:ys) = f x y:zipWithDefaults f x0 y0 xs ys -- | The 'indexDefault' function indexes into a list like @(!!)@, but -- when it runs off the end either returns the given default or, if no -- default is given, sticks with the last element. indexDefault :: Maybe a -> [a] -> Int -> a indexDefault _ _ i | i<0 = error "negative index" indexDefault _ (x:_) 0 = x indexDefault Nothing [x] _ = x indexDefault (Just x) [] _ = x indexDefault m (_:xs) i = indexDefault m xs (i-1) indexDefault Nothing [] 0 = error "no ultimate element"