list - 列表元组的函数
问题描述
如果这个问题非常琐碎,我很抱歉,但我已经努力寻找答案很长一段时间了,这就是我决定在这里发布它的原因。
我想构建一个函数,它采用二进制元组列表: [(Integer, Integer)] 并从所有元组的所有第二个整数中输出最大整数。我写了以下代码:
maxSecond:: [(Integer,Integer)] -> Integer
maxSecond [(ks, as)] = aux (unzip [(ks, as)])
where aux ([ks],[as]) = maximum ([as])
但它只有在我输入一个只有 1 个元组的列表并为超过 2 个元组的列表输出“函数中的非详尽模式”错误时才有效。我的问题不是如何实际解决原始问题,而是为什么这种方法在 Haskell 中不起作用?
我还编写了以下函数:
aaa:: ([Integer], [Integer]) -> Integer
aaa ([as],[ms]) = 10
显然不可能在 Haskell 中输入列表元组(除非列表不是由 1 个元素组成的)。对此有什么解释吗?
谢谢!!
解决方案
初学者 Haskell 程序员常犯的一个错误是他们认为这[x]
是一个匹配任意长度列表的模式。但[x]
实际上是一种匹配单例列表的模式(一个只有一个元素的列表,并且该元素“链接”到x
)。
如果我们希望能够处理空列表([]
)或非空列表(长度大于零),我们可以写为 pattern x
,x
而不是“链接”到该列表本身。请注意,我们可以使用任何我们想要的标识符。列表的模式匹配当然很有用:例如处理空列表、cons、恰好包含一、二、三、五等元素的列表的情况。但在这里我们只会限制自己,让事情变得更复杂。
为了计算元组的第二项的最大值,我们可以通过首先map
生成一个元素列表的 ping 来处理它,每个元素都是对应元组的第二项,然后我们可以计算该maximum
列表的:
maxSecond :: Ord a => [(a, a)] -> a
maxSecond xs = maximum (map snd xs)
因此,我们在这里使用该map :: (a -> b) -> [a] -> [b]
函数将函数应用于列表中的所有元素xs
,该函数snd :: (c, d) -> d
因此采用 2 元组的第二个元素,然后我们计算maximum :: Ord e => [e] -> e
以获得该列表的最大值。
我们也可以使用(.) :: (b -> c) -> (a -> b) -> a -> c
操作符,写成这样:
maxSecond :: Ord a => [(a, a)] -> a
maxSecond = maximum . map snd
推荐阅读
- python-3.x - 迭代所有页面和爬虫表的元素,在 Python 中保存为数据框
- excel - 在页脚中设置文本格式
- javascript - 如何在打字稿中形成数组数组?
- javascript - Webpack esm 模块解析“../node_modules/react-bootstrap/esm/index.js 中的警告”
- c# - MongoDB .NET - 按名称获取 IMongoCollection
- c++ - cfmakeraw() 在 Macos X / Unix C / C++ 上可用吗?
- javascript - 如何将对象数组转换为基本对象?
- ruby - 通过厨师的 rspec 测试运行 ntpq -p 命令
- cmake - 如何使 CMake 的 add_custom_command(TARGET ... POST_BUILD ...) 依赖于常规文件?
- sql - 使用 azcopy 将 .bak 文件复制到 Azure 存储