(Examples from v0.7) To form a complete insult, simply pass the name or plaintext string into the insult function: insult :: String -> IO () syntax: insult "Name" The insult will be printed out. To obtain a string, use the insultMe function: insult :: String -> String syntax: insultMe "Name" The insult function has two parts. First, they generate a seed, a huge Integer from the name. You can do this using: seedMe :: String -> Integer syntax: seedMe "Name" Note that Integer is required, as opposed to Int, since the numbers are too high. The second part is to take the seed and convert it into an insult. You can do this manually using: makeInsult :: Integer -> String syntax: makeInsult seed The makeInsult process works by breaking the seed down, making it smaller and smaller as the insult grows larger and larger. When the seed runs out, the insult is complete. This process causes the generated insult to be totally unique for that given name. You can watch the progress of the seed by editing the code file, and finding the line near the top of the program: showSeeds = False change it to: showSeeds = True Then your generated insults (by any function) will contain seed progress reports in brackets the whole time. Note that insults with seed progress reports will not work for the backwards process. You can avoid copying insults out to a file by using the insultToFile function: insultToFile :: String -> String -> IO () syntax: insultToFile "filename" "plainText" This performs the same actions as the insult function, but also saves it to the file specified in the first argument. The true power of the insult generator comes in the backwards system which can take any complete insult generated by insultMe and convert it back to the original name or plaintext which generated it. (How amazing!) BACKWARDS INSULT SYSTEM: The system is divided into more steps than are technically required, but allow you to observe the backwards process in detail. The process consist of this: Go through the insult, from the end to the start. Start with a seed of 0. For every component found, such as a noun, or adjective, use it to build up the seed. When a pack of adjectives is found, this needs to be added to the seed as well (this must be done AFTER the adjectives when going backwards). When a subinsult begins, it also needs to be built up into the seed. Creating a back-form string (The old manual way to do it) The manual way to do it is to write a "back form string" of the insult. In this way, you must convert the insult into a special format which tells the back generator what types of terms the terms are. Every time you see a term from the terms list, write the name of the term type, followed by a "|" and then the term itself. For example, the adjective "smelly" would be listed as: "adj|smelly" Each term must be separated by '$' signs. The term types are as follows: you are adj noun plnoun winoun verb and newins See the section starting at line 193 for the contents of these term types. In addition, before blocks of adjectives in the main insult (not the final insult containing only adjectives) you need to specify the number of adjectives before the set of adjectives like this: "numadj|x" where x is the number of adjectives. Finally, you must specify the type of subinsult before the subinsult. (Subinsults are the parts that begin with "with", "who" or "and"). Use this term: "subins|x" where x is a number corresponding to the type, out of one of the following: 0 = With 1 = Who 2 = And 3 = With + Who 4 = With + And 5 = Who + And The final thing to remember is, the final insult is special (if it exists) - it has no noun. It is just a list of adjectives. You do not need the "you", "are" or "numadj" terms for the final insult. So here is an example of an insult: "You would get pwned by a scruffy-looking stuck-up bladder-sack, who eats poo. And, you are expendable and insulting." (Stored in the program as manExampleIns) Its "back form string" form is this: "you|You $ are|would get pwned by $ numadj|2 $ adj|scruffy-looking $ adj|stuck-up $ noun|bladder-sack $ subins|1 $ verb|eats $ plnoun|poo $ adj|expendable $ adj|insulting" (Stored in the program as manExampleBackForm) Fortunately, a new function allows you to convert the pure insult string into back form flawlessly: convertToBackForm :: String -> String syntax: convertToBackForm insultText This will convert the insult above top, into the back form above, lower. This back form string can be converted into list form using backStringToBackList :: String -> [(String, String)] syntax: backStringToBackList backFormString Passing the above example into backStringToBackList gives: [("you","You"),("are","would get pwned by"),("numadj","2"),("adj","scruffy-looking"), ("adj","stuck-up"),("noun","bladder-sack"),("subins","1"),("verb","eats"),("plnoun","poo"), ("adj","expendable"),("adj","insulting")] (Stored in the program as manExampleListForm) You can use this list to find the original seed with: backListParse :: [(String, String)] -> Integer syntax: backListParse backList Returns the original seed used. You can trace the seed all the way back using: backListParseDebug :: [(String, String)] -> String same syntax as backListParse. wrap putStr around it to see the list properly: usage: putStr (backListParseDebug backList) This should show you the same list of seeds as shown in an insult generated when showSeed = True. For example, evaluating: putStr $ backListParseDebug manExampleListForm yields: 0 20 604 3024 12097 72583 1016171 29468973 854600232 2563800696 15382804181 15382804181 Which is the same seed progression as you get when you encode this insult. backListParse returns only the final seed, 15382804181. The final step is to convert the seed back to the original name or plaintext: unSeed :: Integer -> String syntax: unSeed seed Returns the original name. For example, passing 15382804181 to unSeed returns the original plaintext: "haskell" Thus ending the backwards conversion process. The entire process is now handled automatically. It can be handled by a single function: takeItBack :: String -> String syntax: takeItBack insult returns the original name or plaintext. takeItBack "You would get pwned by a scruffy-looking stuck-up bladder-sack, who eats poo. And, you are expendable and insulting." returns "haskell" Just as proof: insultMe "haskell" returns "You would get pwned by a scruffy-looking stuck-up bladder-sack, who eats poo. And, you are expendable and insulting." This demonstrates that we have a very complex and difficult to crack cypher system. The system now has no known problems with it. It should hold true that: takeItBack (insultMe str) == str For all String values of str (ignoring case and punctuation).