I am trying to delete every space between words and uppercase every letter of a word with foldr.
I have tried it with map:
deleteSpaces:: String -> String
deleteSpaces word = (filter(not . isSpace) .unwords . map (\(x:xs) -> (toUpper x):xs) . words) word
it works.
But with foldr I always get an error:
deleteSpacesF :: String -> String
deleteSpacesF word = (filter(not . isSpace) . unwords . foldr (\(x:xs) acc -> (toUpper x) : xs : acc) [] . words) word
I have also tried (\x acc -> (toUpper (head x)):(tail x):acc)
The error is:
• Couldn't match type ‘Char’ with ‘[Char]’ Expected: String Actual: Char • In the first argument of ‘(:)’, namely ‘(toUpper x)’ In the expression: (toUpper x) : xs : acc In the first argument of ‘foldr’, namely ‘(\ (x : xs) acc -> (toUpper x) : xs : acc)’
CodePudding user response:
x
is a Char
, not a String
, so head x
and tail x
, make no sense. You use x
as the head and xs
as the tail, so.
Here it thus looks like:
deleteSpacesF :: String -> String
deleteSpacesF = concat . foldr (\(x:xs) -> ((toUpper x : xs) :)) [] . words
you can also omit the concat
with:
deleteSpacesF :: String -> String
deleteSpacesF = foldr (\(x:xs) -> (toUpper x :) . (xs )) [] . words
CodePudding user response:
You could do something like this:
process = concat . map cap . words
where
cap [] = []
cap (x:xs) = (toUpper x):xs
This defines a helper function to capitalise the first letter, which can then be mapped over each word derived from splitting the original string.
Note that words
will also treat tabs and newlines as separators along with regular spaces, so you may need to modify that if you only care about space characters.