I have a function that takes a substring and a string and finds matching occurrences of the substring in the string and changes matching characters to uppercase. For example:
> upperCase "aaa" "---aaa---"
"---AAA---"
I'd like to use this function, but apply the upperCase operation using several substrings. For example:
> upperCases ["aaa", "bbb", "c"] "d---aaa---c--bbb"
"d---AAA---C--BBB"
What I'm struggling to understand is how I can do this. Here's my best attempt:
upperCases [] st = st
upperCases [x] st = upperCase x st
upperCases (x:xs) st = upperCases xs st
When I use this upperCases function in the example above, I get the following incorrect output:
"d---aaa---C--bbb"
Only the last substring is being changed. What is wrong with this function and I can I write a function to perform the example operation?
You're simply "throwing away" the x from the pattern x:xs. Obviously, you need to use that first before recursing to the other matches!
upperCases (x:xs) st = upperCases xs $ upperCase x st
However, it would be better to not write out the recursion explicitly. What you want is basically, chaining together a bunch of functions. That's a fold:
chain :: [a -> a] -> a -> a
chain = foldr (.) id
Now, at the moment you don't have functions a->a. Rather, you have b->a->a, where both b and a are in fact String. But you can apply the first argument partially, e.g.
[upperCase "aaa", upperCase "bbb", upperCase "c"] :: [String -> String]
More concisely, this list could be defined by map upperCase ["aaa", "bbb", "c"].
So all in all, you need
upperCases = foldr (.) id . map upperCase
Actually, you can even include the upperCase in the fold:
upperCases = foldr ((.) . upperCase) id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With