【问题标题】:haskell list maximum by hand手动最大的haskell列表
【发布时间】:2021-12-20 02:44:23
【问题描述】:

我确实有以下问题:

我得到一个输入(整数列表),我想输出一个三元组(列表的长度、列表的总和以及列表的最大值)。

我确实有以下功能:

lengthSumMax :: Num a => [a] -> (Int, a, a)
lengthSumMax [] = (0, 0, 0)
lengthSumMax x = (length x, sum x, maximum x) --maximum is just a place holder

我知道最大值不起作用,因为我在此函数中没有 Ord。有没有一种递归方法,您可以在不使用 Ord 或辅助函数的情况下“手动”找到列表的最大值?

【问题讨论】:

  • 如果你得到Integers的列表,那么签名应该是[Integer] -> (Int, Integer, Integer),或者你可以使用Integral a => [a] -> (Int, a, a),因为Integral a暗示Ord a。另一种可能性是使用排序函数来确定两个项目中哪一个是最大的。
  • Num 可以是一个复数,其中不清楚如何比较大小。你能用比 Num 更窄的东西吗,比如 Real?

标签: list haskell


【解决方案1】:

有没有一种递归方式,您可以在不使用 Ord 或辅助函数的情况下“手动”找到列表的最大值?

项目的类型需要是 Ord 类型类的成员,才能了解“两个项目中最大的一个”的含义:Ord 类型类定义了诸如 >、<、等来确定哪个项目是最大的。 maximum 与Ord 一起使用,否则检索最大值没有多大意义。

通过递归执行此操作并不意味着可以删除Ord 类型约束。事实上,我们可以实现maximum,但我们仍然需要知道最大值是多少。我们可以使用一个函数,例如isLarger,它确定两个参数中的哪一个是最大的项目,或者返回最大的项目。

我们可以在这里使用递归,并调用列表的尾部,然后相应地更新项目:

lengthSumMax :: (Num a, Ord a) => [a] -> (Int, a, a)
lengthSumMax [] = (0, 0, 0)
lengthSumMax (x:xs) = (…, …, …)
    where (l, s, m) = lengthSumMax xs

您仍然需要填写… 部分。对于这些,您可以使用列表的第一个元素x、长度l、总和s,以及列表其余部分的最大值m。请注意,对于非空列表,您的最大值将返回 0,因此将始终大于或等于零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2021-12-23
    • 2019-04-03
    相关资源
    最近更新 更多