如何将一个列表压缩到嵌套在 Haskell 中的另一个列表之上?
How can I zip a list over another list that is nested in Haskell?
所以,这是一个类型定义,仅用于某些上下文:
type Name = String
type Coordinates = (Int, Int)
type Pop = Int
type TotalPop = [Pop]
type City = (Name, (Coordinates, TotalPop))
这是一个数据集:
testData :: [City]
testData = [("New York City", ((1,1), [5, 4, 3, 2])),
("Washingotn DC", ((3,3), [3, 2, 1, 1])),
("Los Angeles", ((2,2), [7, 7, 7, 5]))]
所以,我正在尝试创建一个函数 (addAllPops
) 来编辑 [City]
中所有 City
的 TotalPop
,并在TotalPop
的开始。我希望它以这样的方式工作,在下面的示例中,输入 addNewPop testData [6, 4, 8]
会将它们更改为:
"New York City", ((1,1), [6, 5, 4, 3, 2],
"Washingotn DC", ((3,3), [4, 3, 2, 1, 1],
"Los Angeles", ((2,2), [8, 7, 7, 7, 5]
只改变一个城市人口的功能就在这里,连同我对整体的尝试,我最大的问题完全是关于将两个列表合并为一个。
addAllPops :: [City] -> [Int] -> [City]
addAllPops [(w, ((x,y), z))] pops = [map uncurry addPop (zip pops z)]
addPop :: City -> Int -> City
addPop (w, ((x,y), z)) p = (w, ((x,y), p:z))
我已经在这个问题上停留了很长一段时间,非常感谢任何和所有的帮助:)
您从 addPop
开始的直觉是一次工作一个。现在看看 zipWith
:
的类型签名
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
它采用逐点运算的函数并将其提升为并行运算两个列表。所以你 zipWith
城市和新元素列表,使用 addPop
逐点组合它们:
addAllPops :: [City] -> [Int] -> [City]
addAllPops cities newPops = zipWith addPop cities newPops
我们可以通过 eta-contract 这个定义来得出非常简单的结果
addAllPops = zipWith addPop
您也可以使用 zip
和 map
来完成此操作,但这只是更多的管道。
所以,这是一个类型定义,仅用于某些上下文:
type Name = String
type Coordinates = (Int, Int)
type Pop = Int
type TotalPop = [Pop]
type City = (Name, (Coordinates, TotalPop))
这是一个数据集:
testData :: [City]
testData = [("New York City", ((1,1), [5, 4, 3, 2])),
("Washingotn DC", ((3,3), [3, 2, 1, 1])),
("Los Angeles", ((2,2), [7, 7, 7, 5]))]
所以,我正在尝试创建一个函数 (addAllPops
) 来编辑 [City]
中所有 City
的 TotalPop
,并在TotalPop
的开始。我希望它以这样的方式工作,在下面的示例中,输入 addNewPop testData [6, 4, 8]
会将它们更改为:
"New York City", ((1,1), [6, 5, 4, 3, 2],
"Washingotn DC", ((3,3), [4, 3, 2, 1, 1],
"Los Angeles", ((2,2), [8, 7, 7, 7, 5]
只改变一个城市人口的功能就在这里,连同我对整体的尝试,我最大的问题完全是关于将两个列表合并为一个。
addAllPops :: [City] -> [Int] -> [City]
addAllPops [(w, ((x,y), z))] pops = [map uncurry addPop (zip pops z)]
addPop :: City -> Int -> City
addPop (w, ((x,y), z)) p = (w, ((x,y), p:z))
我已经在这个问题上停留了很长一段时间,非常感谢任何和所有的帮助:)
您从 addPop
开始的直觉是一次工作一个。现在看看 zipWith
:
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
它采用逐点运算的函数并将其提升为并行运算两个列表。所以你 zipWith
城市和新元素列表,使用 addPop
逐点组合它们:
addAllPops :: [City] -> [Int] -> [City]
addAllPops cities newPops = zipWith addPop cities newPops
我们可以通过 eta-contract 这个定义来得出非常简单的结果
addAllPops = zipWith addPop
您也可以使用 zip
和 map
来完成此操作,但这只是更多的管道。