Reputation: 1829
Knowing little about string manipulation libraries I wanted to write these simple transformations in Haskell myself. I was suprised how much boilerplate I was able to produce. How can I simplify it? Would using regex produce most readable code?
Desired output:
*Main> prettyCamel "foo-bar-example" "fooBarExample" *Main> prettyCapitals "foo-bar-example" "FooBarExample"
Code:
import Data.Char
prettyCapitals = foldr1 (++) . (map capitalize) . splitString
prettyCamel = foldr1 (++) . camelCase . splitString
capitalize (x:xs) = toUpper x : xs
camelCase [] = []
camelCase (x:xs) = x : (map capitalize xs)
splitString :: String -> [String]
splitString = foldr (splittingAdd (== '-')) []
splittingAdd splitPredicate char words =
if splitPredicate char
then "":words
else (char : headOrEmpty words) : tailOrEmpty words
headOrEmpty [] = ""
headOrEmpty (x:xs) = x
tailOrEmpty [] = []
tailOrEmpty (x:xs) = xs
Upvotes: 0
Views: 552
Reputation: 363627
How about using plain old recursion?
prettyCamel "" = ""
prettyCamel ('-':c:s) = toUpper c : prettyCamel s
prettyCamel (c:s) = c : prettyCamel s
prettyCapitals (c:s) = toUpper c : prettyCamel s
Alternatively, you can get a point-free version of one of the functions with the Data.List.Split
package.
prettyCapitals = concatMap capitalize . splitOn "-"
prettyCamel s = x : prettyCapitals xs
where (x:xs) = splitOn "-" s
(Using your previous definition of capitalize
.)
Upvotes: 6
Reputation: 47392
Use libraries and composition!
import Data.Char (toUpper)
import Data.List.Split (splitOn)
capitalize (c:cs) = toUpper c : cs
prettyCaps = concatMap capitalize . splitOn "-"
prettyCamel s = let (w:ws) = splitOn "-" s in w ++ concatMap capitalize ws
Works as expected:
>> prettyCaps "foo-bar-example"
FooBarExample
>> prettyCamel "foo-bar-example"
fooBarExample
Upvotes: 2
Reputation: 71999
foldr1 (++)
is available in the standard library; it's called concat
. splitString
is available in the text
library for the data type Text
as split (== '-')
, in the MissingH
library as split "-"
, in the split
library as splitWhen (== '-')
, or in the bytestring
library for data type ByteString
as split (== '-')
.
Upvotes: 1