0

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
1
  • 1
    Regex is not at all idiomatic code for haskell. Commented Jan 21, 2014 at 17:52

3 Answers 3

6

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Pattern matching is a very powerful tool.
2

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

Comments

1

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 (== '-').

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.