递归遍历列表中的列表

时间:2021-04-29 16:58:14

标签: haskell

我有一些这样的代码:

data Set = Set String [Int]
  deriving (Show, Read)
getArr :: Set -> [Int]
getArr (Set _ arr) = arr

我的目标是编写一个将值列表输入到元组中的函数。 例如: 数据 - "One" [1], "Two" [2], "Three" [3] 输出:"One" [0, 1], "Two" [1,2], "Three" [3,3] 输入为 [0, 1, 3]

我对此的一般方法是递归地逐个遍历数据,同时使用 : 将其添加到第一个索引中一个一个地遍历值列表。

我尝试做类似的事情:

addToSet :: [Set] -> [Int] -> [Set]
addToSet [] [] = []
addToSet (x:xs) (y:ys) = (getArr x : y) ++ addToSet xs

但我收到一条错误消息:

Couldn't match type ‘[Int]’ with ‘Set’
  Expected type: [Set]
    Actual type: [[Int]]```

1 个答案:

答案 0 :(得分:2)

考虑辅助函数

updateSet :: Set -> Int -> Set
updateSet (Set s xs) y = Set s (y:xs)

这只是将单个值添加到给定的集合中:

>>> updateSet (Set "One" [1]) 0
Set "One" [0,1]

那么 addToSet 只是对 zipWith 的包装:

addToSet :: [Set] -> [Int] -> [Set]
addToSet = zipWith updateSet

updateSet 对第一个集合和第一个整数调用,然后是第二个集合和第二个整数,依此类推,结果按顺序组合在一个列表中。


另一种思考方式是将 (Set, Int) -> Int 类型的函数映射到将两个列表压缩在一起的结果上:

updateSet' :: (Set, Int) -> Set
updateSet' (Set s xs, y) -> Set s (y:xs)

addToSet :: [Set] -> [Int] -> [Set]
addToSet ss is = map updateSet' (zip ss is)

注意 updateSet' = uncurry updateSet

相关问题