I am converting the zxcvbn password strength algorithm to Haskell.
I have two functions that check for all characters being ASCII and that a brute force attack is possible:
filterAscii :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filterAscii = filter $ all (\ chr -> ord chr < 128)
and
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
I composed these into a single function:
filtered :: [String] -- ^terms to filter
-> [String] -- ^filtered terms
filtered = filterAscii . filterShort
I now have need to compose these with a third filter to check if the terms are not null:
filter (not . null) terms
It has occurred to me that I am creating a chain of filters and that it would make more sense to create a single function that takes a list of filter functions and composes them in the order given.
If I recall from my reading, this is a job for an applicative functor, I believe. Can I use applicatives for this?
I am not sure how to handle the filterShort
function where I need to zip
each item with its one-based index before filtering.