我有時會發現自己寫的代碼這樣的長度一種更好的方式:比計數單位名單
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