2012-12-31 146 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会存在一些问题,因为它不是纯粹的过滤器。