Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capitalize the first letter of a string and lowercase the rest in Haskell

Tags:

string

haskell

I have to write a function which uppercase the FIRST letter of a string and also LOWERCASE the rest of the string (This string contains random uppercased or lowercased letters).

So far, I have managed to do this:

capitalised :: String->String
capitalised [] = []
capitalised x
            | length x == 1 = map toUpper x
            | otherwise = capitalised (init x): map toLower (last x)

and all other sort of weird functions, and I still could not figure it out.

Please help! Tx in advance!

Forgot to mention, the problem states that I need to write a recursive solution!

like image 660
donkey Avatar asked Nov 20 '13 10:11

donkey


People also ask

How do you capitalize the first letter and lowercase the rest?

To capitalize the first letter of a string and lowercase the rest, use the charAt() method to access the character at index 0 and capitalize it using the toUpperCase() method. Then concatenate the result with using the slice() method to to lowercase the rest of the string.

Which function is capitalized the first character of the text and change the rest of the characters to lowercase?

Select the text for which you want to change the case. Go to Home > Change case . Do one of the following: To capitalize the first letter of a sentence and leave all other letters as lowercase, click Sentence case.

How do you uppercase a string in Haskell?

map toUpper capitalises a String, by making each letter uppercase, so map (map toUpper) capitalises each String in a list of Strings.

How do you capitalize the first letter of a string?

To capitalize the first character of a string, We can use the charAt() to separate the first character and then use the toUpperCase() function to capitalize it. Now, we would get the remaining characters of the string using the slice() function.


2 Answers

Remember that a String is just a type synonym for [Char]? Here we utilize that:

import qualified Data.Char as Char

capitalized :: String -> String
capitalized (head:tail) = Char.toUpper head : map Char.toLower tail
capitalized [] = []

Here is a recursive version:

capitalized :: String -> String
capitalized [] = []
capitalized (head:tail) = Char.toUpper head : lowered tail
  where
    lowered [] = []
    lowered (head:tail) = Char.toLower head : lowered tail
like image 156
Nikita Volkov Avatar answered Jan 03 '23 23:01

Nikita Volkov


Warning: This solution is likely overkill, and not for newbies, but here's how to do it using traversals from the lens package.

import Control.Lens
import Data.Char

capitalize :: *really scary type would go here*
capitalize = over _head toUpper . over (_tail.each) toLower

Where _head and _tail are from Control.Lens.Cons, each is from Control.Lens.Each, and over is from Control.Lens.Setter.

The nice thing about this definition is that it should work with Seq, Vector, Text and other datatypes besides String, because they all are instances of Cons and Each. For example:

import qualified Data.Text as T
import qualified Data.Sequence as S

over _head toUpper . over (_tail.each) toLower $ "aA"
-- "Aa"
over _head toUpper . over (_tail.each) toLower $ T.pack "aA"
-- "Aa"
over _head toUpper . over (_tail.each) toLower $ S.fromList "aA"
-- "Aa"

Edit: Here's one more way to do it, just for the hell of it.

import Data.Char 
import Control.Lens 
import Control.Arrow (***)

over _Cons (toUpper *** over each toLower) "aA"
like image 40
danidiaz Avatar answered Jan 04 '23 00:01

danidiaz