【问题标题】:Filter List of Tuples with longest String过滤具有最长字符串的元组列表
【发布时间】:2019-02-13 20:08:52
【问题描述】:

我是 Haskell 的新手,我正在尝试在使用第二个元素的(字符串)长度并返回正确的元组(如果有的话)时过滤元组列表。

Prelude> let lst = [(a,rr), (b,rr), (c, rrr), (d, rrrr)]

Prelude> filter ((>4).(length snd)) lst

[d, rrrr)]

尝试执行时出错,该长度的参数太多..

谁能帮帮我。非常感谢!

【问题讨论】:

  • 应该是(>4) . length . snd

标签: haskell filter tuples string-length


【解决方案1】:
filter ((>4).(length snd)) lst

看起来您对此有正确的想法,但正如您所注意到的,它无法编译。尽管当我尝试时,该错误与您提到的关于 length 有太多参数的错误不同 - 您在这里给了它一个参数,这是正确的数字。但是,您给它的参数是一个函数(snd,它为您提供一对中的第二个元素),并且它需要一个列表 - 因为无法将函数视为列表,编译器会拒绝这毫无意义。 (即使这不是问题,length snd 会导致 Int,并且您不能将其用作 . 运算符的参数,它需要在任一侧使用函数。这就是 GHC实际上在我尝试运行您的代码时抱怨:Couldn't match expected type '([Char], [Char]) -> Integer' with actual type 'Int' In the second argument of '(.)', namely '(length snd)')

@WillemVanOnsem 已经向您展示了如何修复它,所以让我们来看看。确实和你的很像:

filter ((>4) . length . snd)) lst

. 运算符,您似乎知道,首先将函数应用到其右侧,然后将其左侧的函数应用于结果。所以表达式(>4) . length . snd 的意思是,给定一对,取第二个元素,然后取它的长度(假设它是一个列表,否则不会编译),然后检查结果数字是否大于 4。换句话说,(>4) . length . snd)(a, [b]) -> Bool 类型的谓词,它告诉您该对的第二个槽中的列表是否有超过 4 个元素。 [术语“谓词”仅表示任何返回 Bool 的函数 - 它是应用于您感兴趣类型的元素的测试,如在 filter 和许多相关函数中使用的那样。] 这当然是你的目标是什么。

总而言之,您的答案与正确答案之间的唯一区别在于length snd(将snd 函数作为length 的参数,这是毫无意义的)和length . snd(通过首先应用snd,然后将length 应用于其结果给出的函数)。它们可能看起来很相似,但它们实际上意味着非常不同的东西。

我相信,通过更多的练习,您将能够自己完成类似的事情,并理解 GHC 在出现编译错误时会告诉您什么。

(PS:您的代码实际上首先失败了,因为arr 等是您没有绑定到任何值的变量。我假设它们都是字符串,尤其是当您提到获取 r..r 值的长度时 - 在这种情况下,它们需要用双引号括起来:("a", "rr") 等等。

【讨论】:

    【解决方案2】:

    修复很重要,但仍然存在必须知道函数中最长字符串长度才能匹配或超过它的问题。如果您不知道最长字段长度并且无法在函数中对其进行编码怎么办? lf 函数吐出最长字符串的长度。我确实认为过滤谓词中的 lambda 更容易理解。

    lf 必须跟踪迄今为止最长的字符串,因此它不能传递元组而只能传递单个值。

    ls = [('a',"rr"), ('b',"rr"), ('c', "rrr"), ('d', "rrrr")]
    lf = (\a b -> if (length $ snd b) > a then (length $ snd b) else a)
    filter (\t -> (length $ snd t) == (foldl lf 0 ls)) ls
    

    [('d',"rrrr")]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2019-04-23
      • 2022-01-16
      • 1970-01-01
      相关资源
      最近更新 更多