#readwise # An applicative password list ![rw-book-cover](https://blog.ploeh.dk/assets/themes/ploeh/images/favicons/favicon.png) ## Metadata - Author: [[Mark Seemann]] - Full Title: An applicative password list - URL: https://blog.ploeh.dk/2018/10/15/an-applicative-password-list/ ## Highlights - Recently, I had a similar problem, but for security reasons, I don't want to divulge what it was. Let's just pretend that I had to guess one of those old demo passwords. There weren't *that* many possible variations, but just enough that I couldn't keep them systematically in my head. • The first letter could be upper or lower case. • The second letter could be *a* or *4*. • The *o* could be replaced with a zero (*0*). • The password could end with an exclamation mark (*!*), but it might also be omitted. Having recently discovered the power of lists as applicative functors, I started F# Interactive (FSI), and wrote the following: ```fsharp > let (<*>) fs l = fs |> List.collect (fun f -> l |> List.map f);; val ( <*> ) : fs:('a -> 'b) list -> l:'a list -> 'b list > [sprintf "%s%s%s%s%s%s"] <*> ["P"; "p"] <*> ["a"; "4"] <*> ["ssw"] <*> ["o"; "0"] <*> ["rd"] <*> [""; "!"];; val it : string list = ["Password"; "Password!"; "Passw0rd"; "Passw0rd!"; "P4ssword"; "P4ssword!"; "P4ssw0rd"; "P4ssw0rd!"; "password"; "password!"; "passw0rd"; "passw0rd!"; "p4ssword"; "p4ssword!"; "p4ssw0rd"; "p4ssw0rd!"] ``` This produces a list of all the possible password combinations according to the above rules. ([View Highlight](https://read.readwise.io/read/01gvstsnd1a4c8zsfk5azkgvxc)) - Notice that every time you add another list with `<*>`, an argument is removed from the resulting function contained in the returned list. When you've applied six lists with the `<*>` operator, the return value is no longer a list of functions, but a list of values. ([View Highlight](https://read.readwise.io/read/01gvstvmpq66188c6sh4ehxff7))