Created
September 15, 2012 23:13
-
-
Save ruthenium/3730291 to your computer and use it in GitHub Desktop.
Convert a string to CamelCase, mixedCase or under_score just like they do in ruby zucker, but in haskell. Not pure strings and lists, POSIX-Regex approach.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Data.Char (toUpper, toLower) | |
{- | POSIX Regex approach. -} | |
import Text.Regex (mkRegex, subRegex, matchRegexAll, Regex) | |
------------------------------------------------------------------------------ | |
{- | Transforms first element of the 'String' using the function given. -} | |
transformFst :: (Char -> Char) -> String -> String | |
transformFst _ "" = "" | |
transformFst f (x:xs) = f x:xs | |
------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------ | |
{- | Converts CamelCase or mixedCase 'String' to snake_string. | |
POSIX Regex approach. | |
Due to the POSIX Regex syntax limitations, this still needs an extra | |
case because the first character of the result could be an underscore. | |
-} | |
toSnake :: String -> String | |
toSnake = downcase . go | |
where | |
downcase = map toLower | |
go s = case subRegex (mkRegex "[A-Z]") s "_\\0" of | |
('_':xs) -> xs | |
x -> x | |
------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------ | |
{- | Converts snake_string to mixedCase 'String'. | |
Uses a custom simple subRegex variant, which accepts a transforming | |
function as an argument, and applies it to all recursively found | |
matches in a 'String' given. | |
NOTE: The regular expression used as a matcher will not match a | |
trailing \"_\" characters, so a 'String' like "\foo_\" will result in | |
a \"Foo_\" return value. | |
-} | |
toMixed :: String -> String | |
toMixed = subRegex' (mkRegex "_[a-zA-Z]+") go | |
where | |
subRegex' :: Regex -> (String -> String) -> String -> String | |
subRegex' r n s = case matchRegexAll r s of | |
Nothing -> s | |
Just (b, m, a, _) -> b ++ n m ++ (subRegex' r n a) | |
go :: String -> String | |
go [] = [] | |
go (x:xs) = transformFst toUpper xs | |
------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------ | |
{- | Converts snake_string to CamelCase 'String'. | |
Actually it is a combinator which upcases the first letter of a | |
'String', previously converted to mixedCase. | |
-} | |
toCamel :: String -> String | |
toCamel = (transformFst toUpper) . toMixed | |
------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------ | |
main = do | |
print . toMixed $ "was_snake_string" | |
print . toCamel $ "was_snake_string" | |
print . toSnake $ "WasCamelCase" | |
print . toSnake $ "wasMixedCase" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment