Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to sequentially apply modifications to a string

Tags:

haskell

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?

like image 685
turtle Avatar asked Feb 10 '26 23:02

turtle


1 Answers

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
like image 63
leftaroundabout Avatar answered Feb 12 '26 21:02

leftaroundabout



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!