diff --git a/aeson-casing.cabal b/aeson-casing.cabal
--- a/aeson-casing.cabal
+++ b/aeson-casing.cabal
@@ -1,6 +1,6 @@
 
 name:                aeson-casing
-version:             0.1.0.5
+version:             0.1.1.0
 synopsis:            Tools to change the formatting of field names in Aeson
                      instances.
 description:         Tools to change the formatting of field names in Aeson
diff --git a/src/Data/Aeson/Casing.hs b/src/Data/Aeson/Casing.hs
--- a/src/Data/Aeson/Casing.hs
+++ b/src/Data/Aeson/Casing.hs
@@ -24,6 +24,7 @@
     , aesonPrefix
 
     , snakeCase
+    , trainCase
     , camelCase
     , pascalCase
     ) where
diff --git a/src/Data/Aeson/Casing/Internal.hs b/src/Data/Aeson/Casing/Internal.hs
--- a/src/Data/Aeson/Casing/Internal.hs
+++ b/src/Data/Aeson/Casing/Internal.hs
@@ -34,11 +34,14 @@
 -- | Snake casing, where the words are always lower case and separated by an
 -- underscore.
 snakeCase :: String -> String
-snakeCase = u . applyFirst toLower
-    where u []                 = []
-          u (x:xs) | isUpper x = '_' : toLower x : snakeCase xs
-                   | otherwise = x : u xs
+snakeCase = symbCase '_'
 
+-- | Train casing, where the words are always lower case and separated by
+-- a hyphen
+
+trainCase :: String -> String
+trainCase = symbCase '-'
+
 -- | Camel casing, where the words are separated by the first letter of each
 -- word being a capital. However, the first letter of the field is never a
 -- capital.
@@ -51,6 +54,13 @@
 pascalCase = applyFirst toUpper
 
 ----
+
+-- | Generic casing for symbol separated names
+symbCase :: Char -> (String -> String)
+symbCase sym =  u . applyFirst toLower
+  where u []                       = []
+        u (x:xs) | isUpper x = sym : toLower x : u xs
+                 | otherwise = x : u xs
 
 applyFirst :: (Char -> Char) -> String -> String
 applyFirst _ []     = []
diff --git a/test/Data/Aeson/Casing/Test.hs b/test/Data/Aeson/Casing/Test.hs
--- a/test/Data/Aeson/Casing/Test.hs
+++ b/test/Data/Aeson/Casing/Test.hs
@@ -27,6 +27,10 @@
 case_pascal = do pascalCase "SampleField" @=? "SampleField"
                  pascalCase "sampleField" @=? "SampleField"
 
+case_train :: Assertion
+case_train = do trainCase "SampleField" @=? "sample-field"
+                trainCase "sampleField" @=? "sample-field"
+
 case_prefix :: Assertion
 case_prefix = dropFPrefix "extraSampleField" @=? "SampleField"
 
@@ -37,19 +41,47 @@
         , personLastName  :: String
         } deriving (Eq, Show, Generic)
 
+data Animal = Animal
+        { animalFirstName :: String
+        , animalBreedName :: String
+        } deriving (Eq, Show, Generic)
+        
+
 instance ToJSON Person where
     toJSON = genericToJSON $ aesonPrefix snakeCase
 instance FromJSON Person where
     parseJSON = genericParseJSON $ aesonPrefix snakeCase
 
+instance ToJSON Animal where
+  toJSON = genericToJSON $ aesonPrefix trainCase
+instance FromJSON Animal where
+  parseJSON = genericParseJSON $ aesonPrefix trainCase
+
+johnDoe = Person "John" "Doe"
+
+johnDoeJSON = "{\"first_name\":\"John\",\"last_name\":\"Doe\"}"
+
+persianEgypt = Animal "Toffee" "Persian Cat"
+
+persianEgyptJSON = "{\"breed-name\":\"Persian Cat\",\"first-name\":\"Toffee\"}"
+
 case_encode_snake :: Assertion
 case_encode_snake = do
-        let p = Person "John" "Doe"
-            b = encode p
-        b @=? "{\"first_name\":\"John\",\"last_name\":\"Doe\"}"
+        let b = encode johnDoe
+        b @=? johnDoeJSON
 
 case_decode_snake :: Assertion
 case_decode_snake = do
-        let b = "{\"first_name\":\"John\",\"last_name\":\"Doe\"}"
-            p = decode b :: Maybe Person
-        p @=? Just (Person "John" "Doe")
+        let p = decode johnDoeJSON :: Maybe Person
+        p @=? Just johnDoe
+
+
+case_encode_train :: Assertion
+case_encode_train = do
+        let b = encode persianEgypt
+        b @=? persianEgyptJSON
+
+case_decode_train :: Assertion
+case_decode_train = do
+        let p = decode persianEgyptJSON :: Maybe Animal
+        p @=? Just persianEgypt
