What is the most standard / general way for zip to track a list?

Traversable- this is in a sense a class of containers whose structure has a "path" (which can correspond to a list), the elements of which can be changed without dissolving the structure. Hence

zipTrav :: Traversable t => t a -> [b] -> Maybe (t (a,b))
zipTrav = evalStateT . traverse zp
 where zp a = do
           bs <- get
           case bs of
              [] -> lift Nothing
              (b:bs') -> put bs' >> return (a,b)

However, going around this list seems a bit hacky and probably not the most efficient way to do this. I would suggest that there will be a standard function that accomplishes the above or more general task, but I cannot figure out what it will be.

+5
source share
1 answer

How about mapAccumL/ mapAccumR?

tzipWith :: Traversable t => (a -> b -> c) -> [a] -> t b -> Maybe (t c)
tzipWith f xs = sequenceA . snd . mapAccumL pair xs
    where pair [] y = ([], Nothing)
          pair (x:xs) y = (xs, Just (f x y))

tzip :: Traversable t => [a] -> t b -> Maybe (t (a, b))
tzip = tzipWith (,)

ghci> tzip [1..] [4,5,6]
Just [(1,4),(2,5),(3,6)]

ghci> tzip [1,2] [4,5,6]
Nothing

- mapAccum , , , . , . , , State ( ST), Traversable t.

+5

Source: https://habr.com/ru/post/1017144/


All Articles