patternMinor
Caesar Shift in Haskell
Viewed 0 times
shiftcaesarhaskell
Problem
I started learning Haskell a couple of days ago and decided to build a Caesar shift in it.
However, this seems far too complex to be the right way of doing it. Any advice?
import Data.Char
shift_str :: Int -> ([Char] -> [Char])
shift_str num
| num > 1 = \str -> shift_str_forwards (shift_str (num-1) str)
| num == 1 = shift_str_forwards
| num == 0 = no_shift
| num == -1 = shift_str_backwards
| num shift_str_backwards (shift_str (num+1) str)
no_shift :: [Char] -> [Char]
no_shift str = str
shift_str_forwards :: [Char] -> [Char]
shift_str_forwards str = map shift_forwards str
shift_str_backwards :: [Char] -> [Char]
shift_str_backwards str = map shift_backwards str
shift_forwards :: Char -> Char
shift_forwards char
| char == 'z' = 'a'
| otherwise = chr (1 + ord char)
shift_backwards :: Char -> Char
shift_backwards char
| char == 'a' = 'z'
| otherwise = chr (ord char - 1)However, this seems far too complex to be the right way of doing it. Any advice?
Solution
First of all, it's great that you use type signatures. However, your using
Next, your shift functions for characters can be simplified by both pattern matching and
Next, your "global" function gets easier if you use
The special cases for
snake_case, whereas Haskell usually uses camelCase for functions, e.g. no_shift should be called noShift.Next, your shift functions for characters can be simplified by both pattern matching and
succ and pred:shiftForwards :: Char -> Char
shiftForwards 'z' = 'a'
shiftForwards c = succ c
shiftBackwards :: Char -> Char
shiftBackwards 'a' = 'z'
shiftBackwards c = pred cNext, your "global" function gets easier if you use
str as an argument and not in a lambda.shiftStr :: Int -> [Char] -> [Char]
shiftStr num str
| num > 0 = shiftStr (num - 1) (map shiftForwards str)
| num < 0 = shiftStr (num + 1) (map shiftBackwards str)
| num == 0 = strThe special cases for
num == 1 and num == -1 aren't necessary, since shiftStr will return immediately if the subsequent call uses num = 0.Code Snippets
shiftForwards :: Char -> Char
shiftForwards 'z' = 'a'
shiftForwards c = succ c
shiftBackwards :: Char -> Char
shiftBackwards 'a' = 'z'
shiftBackwards c = pred cshiftStr :: Int -> [Char] -> [Char]
shiftStr num str
| num > 0 = shiftStr (num - 1) (map shiftForwards str)
| num < 0 = shiftStr (num + 1) (map shiftBackwards str)
| num == 0 = strContext
StackExchange Code Review Q#148307, answer score: 6
Revisions (0)
No revisions yet.