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?
An empty char value does not belong to any char, so Java gives a compile-time error. To create an empty char, we either can assign it a null value \0 or default Unicode value \u0000 .
A String in Haskell is a list of characters. So to match the empty String you need to match an empty list ( [] ). Your pattern (x:xs) will only match lists or String s with at least one element because it consists of one element ( x ) and the rest ( xs ), which could be empty or non-empty.
An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With