Q:

How to add number as string to string in haskell

I am trying to encrypt the string "aaaabbccdeee" gets converted into "a4bbccde3"
I wasn't able to get it working in one function
Working Solution 1:
import Data.List (group)
gab0 :: [Char] -> [(Char, Int)]
gab0 = map(\l@(x:xs) -> (x, length l)) . group

gab1 :: (Char, Int) -> String
gab1 (d, 1) = [d]
gab1 (d, 2) = [d] ++ [d]
gab1 (d, x) = [d] ++ show x

gab :: [(Char, Int)] -> String
gab = foldr(\x acc ->  gab1 x ++ acc) [] 

{-
 - gab $ gab0 ['a', 'a', 'a', 'b', 'c', 'c','c','c','d','e','e']
"a3bc4de2"
-}

Solution 2 not working:
gab2 :: [Char] -> Int -> [Char]
gab2 [x] n 
    | n > 1 = [x] ++ show n
    | otherwise = [x]
gab2 (x:y:xs) n
    | x == y = gab2 (x:xs) (n + 1)
    | otherwise = getnum x :  gab2 (y:xs) 0 
    where getnum a = [a] ++ show n ++ []

"aaaabbccdeee" transformed to "a4bbccde3"

A:

Sounds like you are trying to compress your first definition into a single function -- i.e. you just need to shuffle some working code around. Haskell is great at this.
I would personally keep gab1 separate, since it has a couple special cases.  Typically it would be written in curried form
gab1 :: Char -> Int -> String
gab1 d 1 = [d]
gab1 d 2 = [d,d]
gad1 d x = [d] ++ show x

When gab0 builds a (Char,Int) pair, the only thing it is ever used for is to be passed to gab1 later.  So we can fuse that layer:
gab0 :: String -> [String]
gab0 = map (\l@(x:_) -> gab1 x (length l)) . group

Now, since we've moved the application of gab1 to gab0 (gosh these need some better names, huh?), gab has been reduced to:
gab :: [String] -> String
gab = foldr (\x acc -> x ++ acc) [] 
    = foldr (++) []
    = concat

(I'm using chained = to indicate multiple reductions in a row -- in the real code you need to pick one, but they are all equivalent).
Since gab is so simple, why don't we just do it as part of gab0?
gab0 :: String -> String
gab0 = concat . map (\l@(x:_) -> gab1 x (length l)) . group

We can move our gab1 into a where clause since it is only used for a limited scope.  I'm going to rename it to renderRun, since it converts a "run" into a string.
gab0 :: String -> String
gab0 = concat . map (\l@(x:_) -> renderRun x (length l)) . group
    where
    renderRun d 1 = [d]
    renderRun d 2 = [d,d]
    renderRun d x = [d] ++ show x

Is that more to your liking?

