如何将列表压缩到嵌套在 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,5]))]

因此,我正在尝试创建一个函数 (addAllPops) 来编辑 TotalPop 中所有 City[City],并在开始时添加一个新条目TotalPop。我希望它以这样的方式工作,在下面的示例中,输入 addNewPop testData [6,8] 会将它们更改为:

"New York City",[6,5,2],"Washingotn DC",[4,1],"Los Angeles",[8,5]

只改变一个城市人口的功能就在这里,连同我对整个城市的尝试,我最大的问题完全是将两个列表合并为一个。

addAllPops :: [City] -> [Int] -> [City]
addAllPops [(w,((x,y),z))] pops = [map uncurry addPop (zip pops z)]

addPop :: City -> Int -> City
addPop (w,z)) p = (w,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

您也可以使用 zipmap 来完成此操作,但只是更麻烦。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...