0

我正在将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使用基于一个的索引的每个项目的功能。

4

2 回答 2

3

您可以使用Endowrapper fromData.Monoid来获取一个 monoid 实例,该实例将允许您mconcat像这样使用:

Prelude> :m + Data.Monoid
Prelude Data.Monoid> :t appEndo $ mconcat [Endo filterAscii, Endo filterShort]
appEndo $ mconcat [Endo filterAscii, Endo filterShort] :: [String] -> [String]
于 2012-12-31T16:48:42.720 回答
2

换句话说,你想要:

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

filter但是您也应该知道,无论如何,GHC(据我所知)很可能会优化 s的管道。所以创建这个函数可能不值得。请注意,filterShort由于它不是纯过滤器,因此您会遇到一些问题。

于 2012-12-31T21:14:44.000 回答