【问题标题】:Get elements with odd length in a Haskell list of strings在 Haskell 字符串列表中获取奇数长度的元素
【发布时间】:2015-09-20 23:33:57
【问题描述】:

我在 Haskell 中有一个字符串列表,我需要在另一个列表中获取那些长度为奇数的元素。如何使用高阶函数(如 foldr、foldl、foldr1、foldl1、filter、map 等)来完成此操作?我将非常感谢您的帮助。在这种情况下可以使用列表推导吗?

【问题讨论】:

    标签: haskell higher-order-functions


    【解决方案1】:

    您似乎知道filter 的存在(因为您已经提到过),但可能不确定它是如何工作的。如果您尝试提取列表的特定子集,这似乎是正确的路径。如果您查看它的类型签名,您会发现它非常简单:

    (a -> Bool) -> [a] -> [a]
    

    也就是说,它需要一个返回 True 或 False 的函数(即 true 包含在新集合中,否则为 false)并生成一个新列表。同样,Haskell 在 Prelude 中提供了一个名为 odd 的函数。它的签名如下:

    Integral a => a -> Bool
    

    也就是说,它可以接受任何Integral类型,如果是奇数则返回True,否则返回false。

    现在,让我们考虑一个解决方案:

    filter odd [1..10]
    

    这将提取 [1,10] 之间的所有奇数。

    我注意到你提到了列表推导。如果您已经获得了一个列表并且您只是在过滤它,您可能不想使用它。然而,列表推导将是一个完全可以接受的解决方案:

    [x | x <- [1..10], odd x]
    

    通常,列表推导式用于表达具有更复杂约束的列表的生成。

    现在,实际回答您的问题。因为我们知道我们可以过滤数字,并且如果我们使用 Hoogle 搜索以下类型(注意 String 就是 [Char]):

    [a] -> Int
    

    您将看到一个length 函数。通过一些函数组合,我们可以快速了解如何创建一个过滤奇数长度的函数。总而言之,我们有odd,它是Int -&gt; Bool(在这种情况下)类型,我们有length,它是[a] -&gt; Int 或者——特别是——String -&gt; Int。我们的解决方案现在如下所示:

    filter (odd . length) ["abc","def","eh","123","hm","even"]
    

    【讨论】:

      【解决方案2】:

      来吧。

      getOddOnes = filter . flip (foldr (const (. not)) id) $ False
      

      注意:如果你把这个作为你的作业,你最好准备好解释它!

      【讨论】:

      • 虽然很可爱,但您的isOddLength 部分却是不必要的复杂。一个更简单的解决方案是getOddOnes = filter $ foldr (const not) False
      • @Cactus,我认为有理由更喜欢左折叠,这个答案是为了在某种意义上匹配问题的性质。
      猜你喜欢
      • 2021-09-19
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多