user3357400
user3357400

Reputation: 397

replace character to number in haskell

I have function change which replace some characters to numbers. Here it is:

change [] = []
change (x:xs) | x == 'A'  = '9':'9':change xs
              | x == 'B'  = '9':'8':change xs
              | otherwise = change xs

and the output is:

Main> change "aAB11s"
"9998" 

but I need this:

Main> change "aAB11s"
"a999811s" 

How can I do this?

Upvotes: 1

Views: 367

Answers (2)

Javran
Javran

Reputation: 3434

In addition to @kostya 's answer, you don't need to write the recursive part youself, try this out:

change :: String -> String
change xs = concatMap chToStr xs
    where chToStr 'A' = "99"
          chToStr 'B' = "98"
          chToStr  x =  [x]

or, more point-freely (actually this is preferred if the point-free refactoring doesn't hurt the readability):

change :: String -> String
change = concatMap chToStr
    where chToStr 'A' = "99"
          chToStr 'B' = "98"
          chToStr  x  = [x]

And you can test the result:

λ> change "aAB11s"
"a999811s"

Some explanation:

It's tempting to do an elementwise replacement by passing map a function f :: Char -> Char. But here you can't do that because for A, you want two characters, i.e. 99, so the function you want is of type Char -> String (String and [Char] in Haskell are equivalent) which does not fit the type signature.

So the solution is to also wrap other characters we don't care about into lists, and afterwards, we can perform a string concatenation(this function in Haskell is called concat) to get a string back.

Further, concatMap f xs is just a shorthand for concat (map f xs)

λ> map (\x -> [x,x]) [1..10]
[[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9],[10,10]]
λ> concat (map (\x -> [x,x]) [1..10])
[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10]
λ> concatMap (\x -> [x,x]) [1..10]
[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10] 

Upvotes: 1

kostya
kostya

Reputation: 9559

Try this:

change [] = []
change (x:xs) | x == 'A'  = '9':'9':change xs
              | x == 'B'  = '9':'8':change xs
              | otherwise = x:change xs

The only change is in otherwise.

Upvotes: 7

Related Questions