Несколько раз я обнаружил, что хочу zip
в Haskell, который добавляет дополнение к более короткому списку вместо того, чтобы обрезать более длинный. Это достаточно легко написать. (Monoid
работает для меня здесь, но вы также можете просто передать элементы, которые вы хотите использовать для заполнения.)
zipPad :: (Monoid a, Monoid b) => [a] -> [b] -> [(a, b)]
zipPad xs [] = zip xs (repeat mempty)
zipPad [] ys = zip (repeat mempty) ys
zipPad (x:xs) (y:ys) = (x, y) : zipPad xs ys
Этот подход становится уродливым при попытке определить zipPad3
. Я набрал следующее, а затем понял, что, конечно, он не работает:
zipPad3 :: (Monoid a, Monoid b, Monoid c) => [a] -> [b] -> [c] -> [(a, b, c)]
zipPad3 xs [] [] = zip3 xs (repeat mempty) (repeat mempty)
zipPad3 [] ys [] = zip3 (repeat mempty) ys (repeat mempty)
zipPad3 [] [] zs = zip3 (repeat mempty) (repeat mempty) zs
zipPad3 xs ys [] = zip3 xs ys (repeat mempty)
zipPad3 xs [] zs = zip3 xs (repeat mempty) zs
zipPad3 [] ys zs = zip3 (repeat mempty) ys zs
zipPad3 (x:xs) (y:ys) (z:zs) = (x, y, z) : zipPad3 xs ys zs
На этом этапе я обманул и просто использовал length
, чтобы выбрать самый длинный список и наложить остальные.
Я не замечаю более элегантный способ сделать это или что-то вроде zipPad3
уже определен где-то?