First of all, it's great that you use type signatures. However, your using 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 c
Next, 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 = str
| num > 0 = shiftStr (num - 1) (map shiftForwards str)
| num < 0 = shiftStr (num + 1) (map shiftBackwards str)
| num == 0 = str
The special cases for num == 1
and num == -1
aren't necessary, since shiftStr
will return immediately if the subsequent call uses num = 0
.