使用列表压缩可遍历的最标准/通用方法是什么?

lef*_*out 5 containers haskell traversable

Traversable在某种意义上,容器类的结构具有"路径"(可以对应于列表),可以在不解散结构的情况下修改其中的元素.于是

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)
Run Code Online (Sandbox Code Playgroud)

但是,列表状态遍历似乎有些过时,可能不是最有效的方法.我认为会有一个完成上述或更一般任务的标准函数,但我无法弄清楚它会是什么.

Ben*_*son 5

怎么样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
Run Code Online (Sandbox Code Playgroud)

关于效率问题 - 在引擎盖下,mapAccum函数使用状态monad,所以我所做的就是在高阶函数中捕获代码的命令部分.我不希望这段代码比你的代码表现更好.但我认为你不能比Statemonad(或ST)做得更好Traversable t.