Rumca
Rumca

Reputation: 1829

Learning Haskell: string transformations

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

Answers (3)

Fred Foo
Fred Foo

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

Chris Taylor
Chris Taylor

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

Sebastian Redl
Sebastian Redl

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

Related Questions