diff --git a/HostAndPort.cabal b/HostAndPort.cabal
--- a/HostAndPort.cabal
+++ b/HostAndPort.cabal
@@ -1,5 +1,5 @@
 name:                HostAndPort
-version:             0.1.0
+version:             0.2.0
 license:             MIT
 license-file:        LICENSE
 author:              Slava Bacherikov
@@ -10,7 +10,9 @@
 category:            Network
 build-type:          Simple
 cabal-version:       >=1.10
-synopsis:            Parser host and port pairs like localhost:22
+tested-with:         GHC == 7.4, GHC == 7.6, GHC == 7.8, GHC == 7.10
+extra-source-files:  README.md
+synopsis:            Parser for host and port pairs like localhost:22
 description:
 
   Simple parser for parsing host and port pairs.
@@ -21,13 +23,19 @@
   .
   Examples:
   .
-    * localhost
-    * localhost:8080
-    * 127.0.0.1
-    * 127.0.0.1:8080
-    * [::1]
-    * [::1]:8080
+  * localhost
+  .
+  * localhost:8080
+  .
+  * 127.0.0.1
+  .
+  * 127.0.0.1:8080
+  .
+  * [::1]
+  .
+  * [::1]:8080
 
+
 library
   exposed-modules:     Network.HostAndPort
   build-depends:       base >=4.5 && <5,
@@ -37,7 +45,7 @@
   default-language:    Haskell2010
 
 test-suite tests
-  default-language:    Haskell2010
+  default-language:    Haskell98
   type:                exitcode-stdio-1.0
   hs-source-dirs:      tests
   main-is:             Spec.hs
@@ -47,7 +55,7 @@
                        hspec
 
 test-suite doctests
-  default-language:    Haskell2010
+  default-language:    Haskell98
   type:                exitcode-stdio-1.0
   hs-source-dirs:      tests
   main-is:             Doctests.hs
@@ -56,6 +64,15 @@
                        HostAndPort,
                        doctest
 
+benchmark bench-hostandport
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      benchmarks
+  main-is:             Benchmark.hs
+  ghc-options:         -O2 -Wall -fno-warn-name-shadowing
+  default-language:    Haskell98
+  build-depends:       base >=4.5 && <5,
+                       HostAndPort,
+                       criterion
 
 source-repository head
   type:                git
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+HostAndPort
+===========
+
+[![Build Status](https://travis-ci.org/bacher09/hostandport.svg?branch=master)]
+(https://travis-ci.org/bacher09/hostandport)
+
+
+Simple Haskell library for parsing connection strings that contain
+host and port info. For more info see package [documentation][docs].
+
+
+License
+-------
+MIT
+
+
+[docs]: https://hackage.haskell.org/package/HostAndPort-0.1.0/docs/Network-HostAndPort.html
diff --git a/benchmarks/Benchmark.hs b/benchmarks/Benchmark.hs
new file mode 100644
--- /dev/null
+++ b/benchmarks/Benchmark.hs
@@ -0,0 +1,18 @@
+module Main where
+import Criterion.Main
+import Network.HostAndPort
+
+
+main :: IO ()
+main = defaultMain [
+        bgroup "ipv4" [ bench "127.0.0.1" $ whnf isIPv4Address "127.0.0.1"
+                      , bench "bad" $ whnf isIPv4Address "22222.2222.222.22"]
+        , bgroup "ipv6" [ bench "::1" $ whnf isIPv6Address "::1"
+                        , bench "vinnica.in" $ whnf isIPv6Address "2605:2700:0:2::4713:9eef"
+                        , bench "full" $ whnf isIPv6Address "1:2:3:4:5:6:7:8"
+                        , bench "with-ipv4" $ whnf isIPv6Address "1:2:3:4:5:6:127.0.0.1"
+                        , bench "bad" $ whnf isIPv6Address "2605:2700:0:2::4713:9eef"]
+        , bgroup "HostAndPort" [ bench "127.0.0.1" $ nf hostAndPort "127.0.0.1"
+                               , bench "localhost:9090" $ nf hostAndPort "localhost:9090"
+                               , bench "ipv6-and-port" $ nf hostAndPort "[2605:2700:0:2::4713:9eef]:26000"]
+        ]
diff --git a/src/Network/HostAndPort.hs b/src/Network/HostAndPort.hs
--- a/src/Network/HostAndPort.hs
+++ b/src/Network/HostAndPort.hs
@@ -1,17 +1,30 @@
-module Network.HostAndPort (
-    isIPv4Address,
-    isIPv6Address,
-    hostAndPort,
-    maybeHostAndPort,
-    defaultHostAndPort
-) where
-import Text.Parsec
-import Control.Applicative hiding((<|>), many)
+module Network.HostAndPort
+    ( ConnectionDetail(..)
+    , RemoteAddr
+    , isIPv4Address
+    , isIPv6Address
+    , hostAndPort
+    , detailedHostAndPort
+    , maybeHostAndPort
+    , defaultHostAndPort
+    ) where
+
+
 import Control.Monad
 import Data.Maybe
+import Control.Applicative hiding((<|>), many)
+import Control.Arrow (second)
+import Text.Parsec
 
 
+data ConnectionDetail a = IPv4Address a
+                        | IPv6Address a
+                        | HostName a
+    deriving(Show, Eq, Ord)
+
+
 type Parser = Parsec String ()
+type RemoteAddr = ConnectionDetail String
 
 
 countMinMax :: (Stream s m t) => Int -> Int -> ParsecT s u m a -> ParsecT s u m [a]
@@ -85,7 +98,7 @@
     last2f = try ipv4address <|> consequence [h4s, hexShortNum]
     last2 f = if f
         then last2f
-        else choice [try $ last2f,
+        else choice [try last2f,
                      try $ consequence [string "::", hexShortNum],
                      consequence [hexShortNum, string "::"]]
 
@@ -122,7 +135,7 @@
 
 
 -- | This function will validate ipv4 address
--- and return True if string is valie adress
+-- and return True if string is valid adress
 isIPv4Address :: String -> Bool
 isIPv4Address = isParsed $ ipv4address <* eof
 
@@ -148,9 +161,13 @@
 asciiAlphaNum = satisfy isAsciiAlphaNum
 
 
-connectionStr :: Parser (String, Maybe String)
-connectionStr = do
-    addr <- try ipv6str <|> try ipv4address <|> hostname
+connectionStr :: (String -> a) ->
+                 (String -> a) ->
+                 (String -> a) -> Parser (a, Maybe String)
+connectionStr ipv6Fun ipv4Fun hostFun = do
+    addr <- try (ipv6Fun <$> ipv6str)
+                <|> try (ipv4Fun <$> ipv4address)
+                <|> (hostFun <$> hostname)
     p <- maybePort
     return (addr, p)
   where
@@ -161,7 +178,30 @@
         return ipv6
     maybePort = option Nothing $ char ':' >> Just <$> port
 
+
 -- | This function will parse it's argument and return either
+-- `String` (`Left`) in case of error or (`ConnectionDetail String`, Maybe Port)
+-- tuple (`Right`).
+--
+-- Examples:
+--
+-- >>> detailedHostAndPort "localhost"
+-- Right (HostName "localhost",Nothing)
+-- >>> detailedHostAndPort "[::1]:3030"
+-- Right (IPv6Address "::1",Just "3030")
+-- >>> detailedHostAndPort "127.0.0.1:1080"
+-- Right (IPv4Address "127.0.0.1",Just "1080")
+--
+-- /Since/ 0.2
+detailedHostAndPort :: String -> Either String (RemoteAddr, Maybe String)
+detailedHostAndPort s = case runParser parser () "" s of
+    (Right v) -> Right v
+    (Left e) -> Left $ show e
+  where
+    parser = connectionStr IPv6Address IPv4Address HostName <* eof
+
+
+-- | This function will parse it's argument and return either
 -- `String` (`Left`) with info about error or (Host, `Maybe` Port)
 -- tuple (`Right`).
 --
@@ -172,9 +212,9 @@
 -- >>> hostAndPort "[::1]:3030"
 -- Right ("::1",Just "3030")
 hostAndPort :: String -> Either String (String, Maybe String)
-hostAndPort s = case runParser (connectionStr <* eof) () "" s of
+hostAndPort s = case runParser (connectionStr id id id <* eof) () "" s of
     (Right v) -> Right v
-    (Left e) -> Left $ show $ e
+    (Left e) -> Left $ show e
 
 
 -- | Function will parse argument and return Maybe (Host, Maybe Port)
@@ -186,9 +226,7 @@
 -- >>> maybeHostAndPort "192.168.10.12:7272"
 -- Just ("192.168.10.12",Just "7272")
 maybeHostAndPort :: String -> Maybe (String, Maybe String)
-maybeHostAndPort s = case hostAndPort s of
-    (Right v) -> Just v
-    (Left _) -> Nothing
+maybeHostAndPort s = either (const Nothing) Just $ hostAndPort s
 
 
 -- | Function will take default port and connection string
@@ -206,4 +244,4 @@
 defaultHostAndPort :: String                    -- ^ default Port number
                    -> String                    -- ^ connection string
                    -> Maybe (String, String)    -- ^ Maybe (Host, Port)
-defaultHostAndPort p s = (\(h, mp) -> (h, fromMaybe p mp)) <$> maybeHostAndPort s
+defaultHostAndPort p s = second (fromMaybe p) <$> maybeHostAndPort s
diff --git a/tests/Spec.hs b/tests/Spec.hs
--- a/tests/Spec.hs
+++ b/tests/Spec.hs
@@ -1,9 +1,14 @@
 module Main where
+import Text.Printf
 import Test.Hspec
 import Network.HostAndPort
-import Text.Printf
 
 
+isLeft :: Either a b -> Bool
+isLeft (Left _) = True
+isLeft (Right _) = False
+
+
 main :: IO ()
 main = hspec spec
 
@@ -90,6 +95,21 @@
         it "testing invalid" $ do
             defaultHostAndPort "60" "localhost:99999" `shouldBe` Nothing
             defaultHostAndPort "60" "[bad]:25" `shouldBe` Nothing
+
+    describe "detailedHostAndPort" $ do
+        it "parsing hosts" $ do
+            detailedHostAndPort "localhost" `shouldBe` Right (HostName "localhost", Nothing)
+            detailedHostAndPort "some-domain.com" `shouldBe` Right (HostName "some-domain.com", Nothing)
+            detailedHostAndPort "42.another-domain.com:3030" `shouldBe` Right (HostName "42.another-domain.com", Just "3030")
+
+        it "parsing ipv6address" $ do
+            detailedHostAndPort "[::1]:8080" `shouldBe` Right (IPv6Address "::1", Just "8080")
+            detailedHostAndPort "[10::1:f]:8080" `shouldBe` Right (IPv6Address "10::1:f", Just "8080")
+            detailedHostAndPort "[::1]:65536" `shouldSatisfy` isLeft
+
+        it "parsing ipv4address" $ do
+            detailedHostAndPort "127.0.0.1" `shouldBe` Right (IPv4Address "127.0.0.1", Nothing)
+            detailedHostAndPort "127.0.0.1:6060" `shouldBe` Right (IPv4Address "127.0.0.1", Just "6060")
   where
     valid f s = it (printf "valid \"%s\"" s) (f s `shouldBe` True)
     invalid f s = it (printf "invalid \"%s\"" s) (f s `shouldBe` False)
