2012-12-31 145 views
0

我正在將zxcvbn password strength算法轉換爲Haskell。撰寫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每個項目與其基於one-based索引之前篩選。

+1

爲什麼現在一切都需要成爲應用函子?好的舊'foldl(。)id'發生了什麼? –

+0

如何使用它來解決我的問題,特別是帶索引部分的'zip'? – Ralph

+0

這會鏈接'[String] - > [String]'函數,而不是'String-> Bool'。 BTW'ap'在這裏並不好,'xs ap ys'將每個'x'應用於每個'y'。 –

回答

2

可以使用Endo包裝從Data.Monoid得到一個獨異的實例,將允許您使用mconcat像這樣:

Prelude> :m + Data.Monoid 
Prelude Data.Monoid> :t appEndo $ mconcat [Endo filterAscii, Endo filterShort] 
appEndo $ mconcat [Endo filterAscii, Endo filterShort] :: [String] -> [String] 
+0

我會看看它。謝謝。 – Ralph

2

換句話說,你想:

filters :: [a -> Bool] -> [a] -> [a] 
filters fs = filter (\a -> and $ map ($ a) fs) 

但你也應該知道,無論如何,filters的流水線很可能由GHC(據我所知)進行優化。所以創建這個函數可能不值得。請注意,您的filterShort會存在一些問題,因爲它不是純粹的過濾器。