Reputation: 397
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
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
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