Ответ 1
Жадный zip может быть аккуратно выражен через неэксклюзивный тип дизъюнкции (в отличие от Either
, который является исключительной дизъюнкцией). Это предлагают два популярных пакета. Один из них - минималистский, без зависимости data-or:
GHCi> import Data.Or
GHCi> :t zipOr
zipOr :: [a] -> [b] -> [Or a b]
GHCi> zipOr [1, 2, 3] [4, 5]
[Both 1 4,Both 2 5,Fst 3]
Другой these, который поставляется с множеством колоколов и свистков:
GHCi> import Data.These
GHCi> import Data.Align
GHCi> :t align
align :: Align f => f a -> f b -> f (These a b)
GHCi> align [1, 2, 3] [4, 5]
[These 1 4,These 2 5,This 3]
Я считаю, что Or a b
и These a b
выражают ваше намерение лучше, чем (Maybe a, Maybe b)
(последний тип включает (Nothing, Nothing)
, который жадный zip никогда не произведет). Тем не менее, вы можете выразить zip'
с помощью zipOrWith
из Data.Or
...
import Data.Or
zip' :: [a] -> [b] -> [(Maybe a, Maybe b)]
zip' = zipOrWith $ \xy -> case xy of
Both x y -> (Just x, Just y)
Fst x -> (Just x, Nothing)
Snd y -> (Nothing, Just y)
... или alignWith
из Data.Align
:
import Data.These
import Data.Align
zip' :: Align f => f a -> f b -> f (Maybe a, Maybe b)
zip' = alignWith $ \xy -> case xy of
These x y -> (Just x, Just y)
This x -> (Just x, Nothing)
That y -> (Nothing, Just y)
Data.Align
, на самом деле, предоставляет вашу функцию под именем padZip
.