寫 「映射f(圖g XS)」 作爲一個調用地圖,你可以寫哈斯克爾,鏈接過濾器
例如XS =地圖(FG)XS
但如何將你寫一個「filter p(filter q xs)」作爲單個調用來過濾?點運算符似乎不像過濾器一樣適用於映射。猜測你會使用其他的謂詞嗎?
寫 「映射f(圖g XS)」 作爲一個調用地圖,你可以寫哈斯克爾,鏈接過濾器
例如XS =地圖(FG)XS
但如何將你寫一個「filter p(filter q xs)」作爲單個調用來過濾?點運算符似乎不像過濾器一樣適用於映射。猜測你會使用其他的謂詞嗎?
如果你定義一個函數both
看起來像這樣:
both :: (a -> Bool) -> (a -> Bool) -> a -> Bool
both f g x = f x && g x
然後,你可以寫:
example xs = filter (both p q) xs
我不知道是否有一個標準功能,這是否適合你。 ..
我會定義一個輔助函數 - 這可能會寫得更具說明性,但我沒有在此係統上安裝GHCI進行測試:
allPredicates :: [a -> Bool] -> a -> Bool
allPredicates [] _ = True
allPredicates (p:ps) x = p x && allPredicates ps x
然後
filter (allPredicates [p, q]) xs
'allPredicates =(。flip($))。翻轉所有' – ephemient
或者稍微少混淆的'allPredicates x y = all(flip($)y)x'。 GHC如何有效地解決「flip」的複雜用法?我以前似乎需要移除用於性能目的的「flip」用法。哦,由於遞歸函數不能內聯,John的'allPredicates'可能表現不佳。哦,奇怪的是,'Data.List'的'all'的定義中沒有'where'...',我相當肯定你需要內聯。 –
啊,不,「靜態參數轉換」使它非遞歸:http://stackoverflow.com/a/9660027/667457 –
爲什麼不列表理解?
example = [x | x <- xs, p x, q x]
-- for example
example = [x | x <- [1..10], (>3) x, x<5 ] -- [4]
調用的東西的功能列表基本上是什麼Control.Monad的ap
功能一樣。然後你只需and
的結果。唯一的一個小丑是ap
要求它的參數都在同一個monad中(在這種情況下是List),所以我們需要用return
來編寫它在這裏工作。
import Control.Monad
filterByMany funcs = filter (and . ap funcs . return)
我會定義一個lambda表達式。
module Main where
overTen :: Int -> Bool
overTen = (>10)
main :: IO()
main = do
print $ filter (\x -> overTen x && even x) [1..20]
輸出:
$ ghci Test.hs
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main (Test.hs, interpreted)
Ok, modules loaded: Main.
*Main> main
[12,14,16,18,20]
*Main>
這就是'GHC -O2'自動執行的事情(差不多:涉及重寫規則的幾個不同階段,中間階段通常在/之前與其他內容相結合,而不是被轉換回過濾器) –
$ ghci Prelude> :m +Control.Arrow Prelude Control.Arrow> :t uncurry (&&) . ((0 <) &&& (< 10)) uncurry (&&) . ((0 <) &&& (< 10)) :: (Num a, Ord a) => a -> Bool Prelude Control.Arrow> filter (uncurry (&&) . ((0 <) &&& (< 10))) [0..15] [1,2,3,4,5,6,7,8,9]
或宣佈自己的運營商,如果你要經常這樣做。
infixr 3 &&:
p &&: q = \a -> p a && q a
infixr 2 ||:
p ||: q = \a -> p a || q a
not' = (.) not
all' = foldr (&&:) $ const True
any' = foldr (||:) $ const False
example xs = filter (p &&: q ||: not' r) xs
import Data.Foldable
import Data.Monoid
p = (>4)
g = (<10)
main = print $ filter (getAll . foldMap (All.) [p,g]) [1..10]
輸出
[5,6,7,8,9]
只因爲名單是可摺疊的,並與All
幺
你可以結合謂語結果怎麼樣是這樣的:
example xs = filter (forAll [p,q,r,s,t,u,v]) xs
forAll:: [(a -> Bool)] -> a -> Bool
forAll funcs x = all (map ($ x) funcs)
你的意思是, 'for all fs x = and [fx | f < - fs]'。 :)對於所有fs x = all($ x)fs'(沒有'map')''all''。 :) –
感謝男人,這確實是eno啊。仍然認爲可能有更直接的方式做到這一點雖然(?) – derp