Reputation: 45
This is my code:
reverseEncode :: Char -> String -> Int -> Char
reverseEncode _ [] _ = ?
reverseEncode c (x:xs) offset
| alphaPos c == (alphaPos x + offset) `mod` 26 = chr (((alphaPos x + offset) + 65) `mod` 26)
| otherwise = reverseEncode c xs offset
It's just a small method used in a virtual Enigma Machine. After writing the function without the second line and testing it, I got this exception:
Non-exhaustive patterns in function reverseEncode
I then realised I didn't tell the function when to stop recursing. This is how that second line of code was born. Obviously, I could just check the length of the string at each step, but it doesn't look as elegant.
Is there anything in Haskell I can put instead of '?' ? If not, is there anything I can define? Or is this something that could be done in a better way?
EDIT: I've actually tried the version with checking the length of the string, and I get the same exception. So how do I make it work?
Upvotes: 4
Views: 1707
Reputation: 477180
There is no empty character. You could however use a character like the Nul character [wiki]. For example with:
reverseEncode :: Char -> String -> Int -> Char
reverseEncode _ [] _ = '\00'
reverseEncode c (x:xs) offset
| alphaPos c == sm `mod` 26 = chr ((sm + 65) `mod` 26)
| otherwise = reverseEncode c xs offset
where sm = alphaPos x + offset
But a more Haskellish approach would be to change the return type. For example by using a Maybe Char
instead. This is often used for "computations that can fail". So we could do this with:
reverseEncode :: Char -> String -> Int -> Maybe Char
reverseEncode _ [] _ = Nothing
reverseEncode c (x:xs) offset
| alphaPos c == sm `mod` 26 = Just (chr ((sm + 65) `mod` 26))
| otherwise = reverseEncode c xs offset
where sm = alphaPos x + offset
Here the Nothing
thus means we reached the end of the list without meeting the condition, and Just x
means that the computation resulted in an answer x
.
Upvotes: 9