I need to write “custom” ord and chr functions. I’m writing a little program to apply a Caesar cipher to a message. What is the fastest way to do this?
The function “ord” only needs to take a character and then return the appropriate number. ‘A’ should return 0, ‘B’ should return 1, etc. Assume that we’re only going to use capital letters, so we only have 26 possibilities. I’d rather not write out 26 guards. Is there a better way to do this? Here’s how they’ll be used. The “chr” function should do the reverse.
caesarencipher::Int->Int->String->String
caesarencipher r s p = map chr . map encipher $ plaintext
where
plaintext = map ord p
encipher p = mod (r*p + s) 26
caesardecipher::Int->Int->String->String
caesardecipher r s c = map chr . map decipher $ ciphertext
where
ciphertext = map ord c
inverser x | mod (r * x) 26 == 1 = x
| otherwise = inverser (x + 1)
decipher c = mod ((inverser 1) * (c - s)) 26
If you really want the fastest way to define custom versions of these functions, then just write out every possible pattern. You can pack multiple clauses onto a line by separating them with semicolons.
However, I don’t see what you’ll gain.
ordandchraren’t any slower just because they handle all codepoints;Charalready stores a complete Unicode codepoint. Indeed,ordshould be basically free, andchrtoo (beyond the simple check for validity). So why not just apply the appropriate numeric offset to the standardordandchrfunctions? (Note that even just writing out the patterns as I suggested above won’t omit error-checking entirely; GHC will throw an exception if a value is passed that none of your clauses handle.)