Dan*_*ton 6 haskell list idiomatic
我有时发现自己编写这样的代码:
someFunc :: Foo -> Int
someFunc foo = length $ do
x <- someList
guard someGuard
return ()
Run Code Online (Sandbox Code Playgroud)
或等效地:
someFunc foo = length [() | x <- someList, someGuard]
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来执行这种计算?更高效?更具可读性?更惯用吗?
普里莫
guard someGuard
return ()
Run Code Online (Sandbox Code Playgroud)
是冗余的,如果条件为真则guard
已经返回()
.然后我想someGuard
实际上取决于x
,否则它会if someGuard then length someList else 0
.通常的写作方式是
someFunc foo = filter (\x -> someGuard) someList
Run Code Online (Sandbox Code Playgroud)
如果情况真的像你的例子看起来那么简单.对于更复杂的情况,使用您的示例样式之一是最直接的方式.如果事情变得非常复杂,我觉得这种做法更可取.
如果您发现自己反复编程到模式,那么要做的是编写一个更高阶的函数来封装该模式.你可以使用你拥有的主体,但是为了完全确信你的代码没有分配,我建议使用foldl
并严格应用增量运算符:
numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n
numberSatisfying p = foldl (\n x -> if p x then (+1) $! n else n) 0
Run Code Online (Sandbox Code Playgroud)
我使用QuickCheck确认此代码与原始代码相同.(是的,QuickCheck将使用随机谓词进行测试非常酷.)