我有一些这样的代码:
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]]```
答案 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
。