Caesar-Cipher Implementation Background

I am a total beginner in Haskell, so after reading the Starting out-chapter of "Learn you a Haskell", I wanted to create my first program that actually does something.

I decided to do the famous Caesar-Cipher.

Code

import Data.Char

encryptChar :: Char -&gt; Int -&gt; Int
encryptChar char shift = if ord char &gt; 64 &amp;&amp; ord char &lt; 91    --Only encrypt A...Z
                           then (if ord char + shift &gt; 90     --"Z" with shift 3 becomes "C" and not "]" 
                                  then ord char + shift - 26
                                  else ord char + shift)
                         else ord char

decryptChar :: Char -&gt; Int -&gt; Int
decryptChar char shift = if ord char &gt; 64 &amp;&amp; ord char &lt; 91
                            then (if ord char - shift &lt; 65
                                   then ord char - shift + 26
                                   else ord char - shift)
                         else ord char

encrypt :: String -&gt; Int -&gt; String
encrypt string shift = [chr (encryptChar (toUpper x) shift) | x &lt;- string]    --"Loop" through string to encrypt char by char

decrypt :: String -&gt; Int -&gt; String
decrypt string shift = [chr (decryptChar (toUpper x) shift) | x &lt;- string]

main = print(decrypt "KHOOR, ZRUOG!" 3)


(The code does work as intended.)

Question(s)


How can this code be improved in general?
Do I follow the style guide of Haskell (indentation, etc.)?
I have a background in imperative languages. Did I do something that is untypical for functional programming languages?


I would appreciate any suggestions.
I'd start by avoiding directly encoding ASCII character codes into the logic. For example, instead of:

if ord char &gt; 64 &amp;&amp; ord char &lt; 91


I'd probably use:

if char &gt;= 'A' &amp;&amp; char &lt;= 'Z'


I think this shows the intent enough more clearly to be worthwhile.
Given that you also do this a couple of different places, I'd probably write a small isUpper function to return a Bool indicating whether a character is an upper-case letter:

isUpper :: Char -&gt; Bool
isUpper char = char &gt;= 'A' &amp;&amp; char &lt;= 'Z'


Then the rest of the code can use that:

encryptChar char shift = if isUpper char     -- ...

decryptChar char shift = if isUpper char     -- ...



[Note: the standard library already has an isUpper, but it may not fit your needs, since it's Unicode-aware, and here you apparently only want to deal with English letters.]