【问题标题】:A better way than counting the length of a list of units比计算单位列表长度更好的方法
【发布时间】:2012-02-12 20:15:20
【问题描述】:

我有时会发现自己在编写这样的代码:

someFunc :: Foo -> Int
someFunc foo = length $ do
  x <- someList
  guard someGuard
  return ()

或等价:

someFunc foo = length [() | x <- someList, someGuard]

有没有更好的方法来执行这种计算?更高效?更具可读性?更地道?

【问题讨论】:

    标签: list haskell idioms


    【解决方案1】:

    普里莫

    guard someGuard
    return ()
    

    是多余的,如果条件为真,guard 已经返回 ()。那我想someGuard实际上依赖于x,否则就是if someGuard then length someList else 0。通常的写法是

    someFunc foo = filter (\x -> someGuard) someList
    

    如果情况真的像您的示例看起来那么简单。对于更复杂的情况,使用您的示例样式之一是最直接的方法。如果事情变得非常复杂,我发现 do-notation 更可取。

    【讨论】:

    • +1 是的,someList 取决于 foosomeGuard 取决于 foox。过滤器表达式可能是捕获它的最简单方法。
    【解决方案2】:

    如果您发现自己重复地对一个模式进行编程,那么要做的就是编写一个高阶函数来封装该模式。您可以使用现有的正文,但为了完全确信您的代码没有分配,我建议使用 foldl 并严格应用增量运算符:

    numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n
    numberSatisfying p = foldl (\n x -> if p x then (+1) $! n else n) 0
    

    我已使用 QuickCheck 确认此代码与您的原始代码等效。 (是的,QuickCheck 将使用随机谓词进行测试非常酷。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 2023-03-29
      • 2019-08-13
      • 2011-08-07
      • 2015-05-09
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多