strong :: String -> Bool
which returns True iff the string passed to it is a "strong" password, which for purposes of the assignment means
- it's at least 15 characters long
- it includes upper case letters
- it includes lower case letters
- it includes digits
Easy enough to write, especially if you import Data.Char, but the lesson is about higher-order functions, and you're urged to use the things taught in the lesson (among which are the character classification functions in Data.Char). So it occurred to me that it would be good to write the function in a way that makes it easy to add other constraints--perhaps it shouldn't be in some list of bad password choices, say.
So, we'd like to write it to take a list of String -> Bool, apply them to the String, and confirm that they all return True. The lesson teaches about all and about map, but we don't want map here.
map :: (a -> b) -> [a] -> [b]
but we want
wonkyMap :: [a -> b] -> a -> [b]
An obvious implementation is
wonkyMap [] _ = []
wonkyMap (f:fs) x = (f x) : (wonkyMap fs x)
though I'm sure it can be written more elegantly as a fold.
(UPDATE: Duh... list comprehensions are your friend.
wonkyMap fs x = [f x | f <- fs]
just as you could define
map f xs = [f x | x <- xs]
There's a pleasing symmetry there.)
Then you have
(UPDATE: Duh... list comprehensions are your friend.
wonkyMap fs x = [f x | f <- fs]
just as you could define
map f xs = [f x | x <- xs]
There's a pleasing symmetry there.)
Then you have
strong password = all $ wonkyMap constraints password
where constraints = [(> 15) . length,
any isUpper,
any isLower,
any isNumber]
OTOH, someone has to have come up with wonkyMap before--and given it a better name. Hoogling the signature, though, didn't turn up anything. Does it look familiar to anyone?
UPDATE: Oops... make that (>= 15) . length
UPDATE: Oops... make that (>= 15) . length
No comments:
Post a Comment