This is my opinion about the first challenge in the cryptopals crypto challenge list. I think I made it quite simple, but I feel it is possible to optimize it even more. Any suggestion?

The code:

```
import qualified Data.HashMap.Strict as HM
import qualified Data.IntMap.Strict as IM
import Data.Maybe
import Data.Char (digitToInt)
import Numeric (readInt)
type BinString = String
type HexString = String
type Base64String = String
base64 = IM.fromList (zip (0..63) (('A'..'Z') ++ ('a'..'z') ++ ('0'..'9') ++ ('+','/')))
hexToBinDict = HM.fromList (('0',"0000"),('1',"0001"),('2',"0010"),('3',"0011"),('4',"0100"),('5',"0101"),
('6',"0110"),('7',"0111"),('8',"1000"),('9',"1001"),('a',"1010"),('b',"1011"),
('c',"1100"),('d',"1101"),('e',"1110"),('f',"1111"))
hexToBase64 :: HexString -> Base64String
hexToBase64 xs = map fromJust (IM.lookup x base64 | x <- base10) ++ padMissingSextets sextets
where base10 = map (fromJust) (map (binToDec) sextets)
sextets = binToSextets (hexToBin xs)
--returns a list of the 4-digit binary encodings of the given string's hex codes
hexToQuartets :: HexString -> (BinString)
hexToQuartets () = ()
hexToQuartets hexCode = fromJust (HM.lookup (head hexCode) hexToBinDict) : hexToQuartets (tail hexCode)
--converts an hex string into a binary string
hexToBin :: HexString -> BinString
hexToBin xs = concat (hexToQuartets xs)
--pads the string with 0's on the right until its a sextet
padRight :: BinString -> BinString
padRight xs = xs ++ (replicate n '0')
where n = 6 - length xs
--returns a list of all full sextets on the string
binToSextets :: BinString -> (BinString)
binToSextets xs = binToSextetsAux (tail xs) () (head xs) 1
--recursiverly find sextets and pad the last one if necessary
binToSextetsAux :: BinString -> (BinString) -> BinString -> Int -> (String)
binToSextetsAux () sextets ys _
|length ys == 6 = sextets ++ (ys)
|otherwise = sextets ++ (padRight ys)
binToSextetsAux xs sextets ys i
|i == 6 = binToSextetsAux (tail xs) (sextets ++ (ys)) (head xs) 1
|otherwise = binToSextetsAux (tail xs) sextets (ys ++ (head xs)) (i+1)
--binary string to decimal conversion
binToDec :: Integral a => BinString -> Maybe a
binToDec = fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt
--pads with "=" on the right for each empty sextet
--if the length is not divisible by 4, then theres 1 or 2 empty sextets
padMissingSextets :: (BinString) -> BinString
padMissingSextets sextets
|(length sextets) `mod` 4 /= 0 = if (length sextets) `mod` 4 == 2 then "=="
else "="
|otherwise = ""
```
```