[英]Composing Haskell filters
我正在將zxcvbn密碼強度算法轉換為Haskell。
我有兩個函數可以檢查所有字符是否為ASCII,並且可以進行蠻力攻擊:
filterAscii :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filterAscii = filter $ all (\ chr -> ord chr < 128)
和
filterShort :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filterShort terms = map fst $ filter long $ zip terms [1..]
where long (term, index) = (26 ^ length term) > index
我將它們組合成一個函數:
filtered :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filtered = filterAscii . filterShort
現在,我需要用第三個過濾器將它們組合起來,以檢查這些術語是否不為空:
filter (not . null) terms
在我看來,我正在創建一個過濾器鏈,並且創建一個具有一系列過濾器功能並按給定順序組合它們的函數會更有意義。
如果我從閱讀中回想起,我相信這是適用於函子的工作。 我可以使用止痛葯嗎?
我不確定如何處理filterShort
函數,該函數需要在過濾之前將每個項目及其基於一個的索引zip
。
您可以使用Data.Monoid
的Endo
包裝器來獲取一個monoid實例,該實例將允許您像下面這樣使用mconcat
:
Prelude> :m + Data.Monoid
Prelude Data.Monoid> :t appEndo $ mconcat [Endo filterAscii, Endo filterShort]
appEndo $ mconcat [Endo filterAscii, Endo filterShort] :: [String] -> [String]
換句話說,您想要:
filters :: [a -> Bool] -> [a] -> [a]
filters fs = filter (\a -> and $ map ($ a) fs)
但您也應該知道,無論如何,GHC很有可能對filter
的管道進行優化。 因此,創建此功能可能不值得。 請注意,由於filterShort
不是純過濾器,因此會有一些問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.