gpt4 book ai didi

haskell - haskell中列表的索引列表

转载 作者:行者123 更新时间:2023-12-02 15:48:10 26 4
gpt4 key购买 nike

我正在寻找一种将列表列表与单个列表合并的方法,以保持列表列表的结构。 IE。一个像这样工作的函数 foo:

foo :: [[a]] -> [b] -> [[(a,b)]]

> foo [[1],[2,2,3],[7,8]] [0..]
[[(1,0)],[(2,1),(2,2),(3,3)],[(7,4),(8,5)]]

(或者与参数相反)

foo :: [b] -> [[a]] -> [[(b,a)]]

> foo [0..] [[1],[2,2,3],[7,8]]
[[(0,1)],[(1,2),(2,2),(3,3)],[(4,7),(5,8)]]

当然,如果我们知道每个列表的长度相等,这个函数可以很容易地创建为:

import Data.List.Split (chunksOf)

foo :: [[a]] -> [b] -> [[(a,b)]]
foo xs ys = chunksOf n $ zip (concat xs) ys
where
n = length $ head xs

但是在更一般的列表长度不等的情况下如何实现这个功能呢?

最佳答案

您可以使用嵌套遍历:遍历外部列表,遍历每个内部列表,并在每一步弹出另一个列表的元素并将其与当前遍历的元素配对。这可以很好地写在状态 monad 中:

import Control.Monad.Trans.State

foo :: ∀ a b . [[a]] -> [b] -> [[(a,b)]]
foo ls ys = evalState nestedTrav ys
where nestedTrav :: State [b] [[(a,b)]]
nestedTrav = forM ls $ \l ->
forM l $ \x ->
state $ \(y:ys) -> (ys, (x,y))

...或更短

foo ls ys = (`evalState`ys)
. forM ls . traverse
$ \x -> state $ \(y:ys) -> (ys, (x,y))

这仅在第二个列表至少与所有第一个列表一样长(或无限长,如您的示例中)时才有效。我建议您通过将遍历版本分解为折叠和/或递归,然后在第二个列表为空时添加中止机制来实现一般情况。

关于haskell - haskell中列表的索引列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73436107/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com