我有时会发现自己写的代码这样的长度一种更好的方式:比计数单位名单
someFunc :: Foo -> Int
someFunc foo = length $ do
x <- someList
guard someGuard
return()
或等价:
someFunc foo = length [() | x <- someList, someGuard]
是否有进行这种更好的办法的计算?更高效?更可读?更习惯?
我有时会发现自己写的代码这样的长度一种更好的方式:比计数单位名单
someFunc :: Foo -> Int
someFunc foo = length $ do
x <- someList
guard someGuard
return()
或等价:
someFunc foo = length [() | x <- someList, someGuard]
是否有进行这种更好的办法的计算?更高效?更可读?更习惯?
如果你发现自己反复编程到一个模式,要做的事情是编写一个高阶函数来封装该模式。你可以使用你的身体,但为了要完全相信,你的代码不分配,我会建议使用foldl
和增量运营商的严格应用:
numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n
numberSatisfying p = foldl (\n x -> if p x then (+1) $! n else n) 0
我已经使用快速检查,以确认此相当于您的原始代码的代码。 (是的,QuickCheck会用随机谓词测试非常酷。)
普里莫
guard someGuard
return()
是多余的,guard
已经返回()
如果条件为真。那么我想someGuard
实际上取决于x
,否则它会是if someGuard then length someList else 0
。通常的写法是
someFunc foo = filter (\x -> someGuard) someList
如果情况真的很像你的例子看起来那么简单。对于更复杂的情况,使用您的示例样式之一是最直接的方法。如果情况变得非常复杂,我觉得这个符号更合适。
+1是的,'someList'依赖于'foo','someGuard'依赖于'foo'和'x'。过滤器表达式可能是最简单的捕获方法。 – 2012-01-18 04:22:56
为什么不'foldl''? – 2012-01-18 06:09:02
@trinithis不在Prelude中... – 2012-01-21 18:59:54