Si considera los índices (implícitos) de cada elemento de una lista como sus claves, entonces zipWith
es una especie de unión interna relacional. Solo procesa las claves para las cuales ambas entradas tienen valores:Función de combinación de unión externa canónica
zipWith (+) [1..5] [10..20] == zipWith (+) [1..11] [10..14] == [11,13,15,17,19]
¿Existe una función correspondiente canónica correspondiente a la unión externa? Algo así como:
outerZipWith :: (a -> b -> c) -> a -> b -> [a] -> [b] -> [c]
outerZipWith _ _ _ [] [] = []
outerZipWith f a' b' [] (b:bs) = f a' b : outerZipWith f a' b' [] bs
outerZipWith f a' b' (a:as) [] = f a b' : outerZipWith f a' b' as []
outerZipWith f a' b' (a:as) (b:bs) = f a b : outerZipWith f a' b' as bs
o tal vez
outerZipWith' :: (a -> b -> c) -> Maybe a -> Maybe b -> [a] -> [b] -> [c]
outerZipWith' _ _ _ [] [] = []
outerZipWith' _ Nothing _ [] _ = []
outerZipWith' _ _ Nothing _ [] = []
outerZipWith' f a' b' [] (b:bs) = f (fromJust a') b : outerZipWith f a' b' [] bs
outerZipWith' f a' b' (a:as) [] = f a (fromJust b') : outerZipWith f a' b' as []
outerZipWith' f a' b' (a:as) (b:bs) = f a b : outerZipWith f a' b' as bs
Así que puedo hacer
outerZipWith (+) 0 0 [1..5] [10..20] == [11,13,15,17,19,15,16,17,18,19,20]
outerZipWith (+) 0 0 [1..11] [10..14] == [11,13,15,17,19,6,7,8,9,10,11]
me encuentro que necesitan de vez en cuando, y yo prefiero usar un lenguaje común a hacer que mi código sea más fácil de escribir (y más fácil de mantener) en lugar de implementar outerZipWith
, o hacer if length as < length bs then zipWith f (as ++ repeat a) bs else zipWith f as (bs ++ repeat b)
.
No 'outerZip :: a -> b -> [a] -> [b] -> [(a, b)]'? – pat
Más como 'outerZip :: (a -> c) -> (b -> d) -> c -> d -> [a] -> [b] -> [(c, d)]' – Apocalisp
Un todo incluido -o tipo (como su 'Estos') puede ser el primer paso necesario. Por lo menos, es un buen lugar para comenzar. – rampion