diff --git a/Data/IP/Addr.hs b/Data/IP/Addr.hs
--- a/Data/IP/Addr.hs
+++ b/Data/IP/Addr.hs
@@ -207,7 +207,7 @@
     toInt n ns = foldl' (\x y -> x * 10 + y) 0 . map digitToInt $ n : ns
 
 ip4 :: Parser IPv4
-ip4 = toIPv4 <$> ip4'
+ip4 = skipSpaces >> toIPv4 <$> ip4'
 
 ip4' :: Parser [Int]
 ip4' = do
@@ -221,6 +221,9 @@
         when (length as /= 4) (fail errmsg)
         mapM_ (test errmsg) as
 
+skipSpaces :: Parser ()
+skipSpaces = void $ many (char ' ')
+
 ----------------------------------------------------------------
 --
 -- IPv6 Parser (RFC 4291)
@@ -251,7 +254,7 @@
     return $ bs1 ++ spring ++ bs2
 
 ip6 :: Parser IPv6
-ip6 = toIPv6 <$> ip6'
+ip6 = skipSpaces >> toIPv6 <$> ip6'
 
 ip6' :: Parser [Int]
 ip6' = ip4Embedded
diff --git a/iproute.cabal b/iproute.cabal
--- a/iproute.cabal
+++ b/iproute.cabal
@@ -1,5 +1,5 @@
 Name:                   iproute
-Version:                1.2.9
+Version:                1.2.10
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
diff --git a/test/IPSpec.hs b/test/IPSpec.hs
--- a/test/IPSpec.hs
+++ b/test/IPSpec.hs
@@ -3,6 +3,7 @@
 
 module IPSpec where
 
+import Control.Applicative
 import Data.IP
 import Safe (readMay)
 import Test.Hspec
@@ -22,10 +23,10 @@
     arbitrary = arbitraryIIPv4Str arbitrary 32
 
 arbitraryIIPv4Str :: Gen IPv4 -> Int -> Gen InvalidIPv4Str
-arbitraryIIPv4Str adrGen msklen = do
-    adr <- adrGen
-    len <- oneof [choose (minBound, -1), choose (msklen + 1, maxBound)]
-    return $ Iv4 $ show adr ++ "/" ++ show len
+arbitraryIIPv4Str adrGen msklen = toIv4 <$> adrGen <*> lenGen
+  where
+    toIv4 adr len = Iv4 $ show adr ++ "/" ++ show len
+    lenGen = oneof [choose (minBound, -1), choose (msklen + 1, maxBound)]
 
 data InvalidIPv6Str = Iv6 String deriving (Show)
 
@@ -33,10 +34,10 @@
     arbitrary = arbitraryIIPv6Str arbitrary 128
 
 arbitraryIIPv6Str :: Gen IPv6 -> Int -> Gen InvalidIPv6Str
-arbitraryIIPv6Str adrGen msklen = do
-    adr <- adrGen
-    len <- oneof [choose (minBound, -1), choose (msklen + 1, maxBound)]
-    return $ Iv6 $ show adr ++ "/" ++ show len
+arbitraryIIPv6Str adrGen msklen = toIv6 <$> adrGen <*> lenGen
+  where
+    toIv6 adr len = Iv6 $ show adr ++ "/" ++ show len
+    lenGen = oneof [choose (minBound, -1), choose (msklen + 1, maxBound)]
 
 ----------------------------------------------------------------
 --
@@ -50,6 +51,10 @@
         prop "IPv6" to_str_ipv6
         prop "IPv4 failure" ipv4_fail
         prop "IPv6 failure" ipv6_fail
+        it "can read even if unnecessary spaces exist" $ do
+            (readMay " 127.0.0.1" :: Maybe IPv4) `shouldBe` readMay "127.0.0.1"
+        it "can read even if unnecessary spaces exist" $ do
+            (readMay " ::1" :: Maybe IPv4) `shouldBe` readMay "::1"
 
 to_str_ipv4 :: AddrRange IPv4 -> Bool
 to_str_ipv4 a = readMay (show a) == Just a
diff --git a/test/RouteTableSpec.hs b/test/RouteTableSpec.hs
--- a/test/RouteTableSpec.hs
+++ b/test/RouteTableSpec.hs
@@ -3,6 +3,7 @@
 
 module RouteTableSpec where
 
+import Control.Applicative
 import Control.Monad
 import Data.IP
 import Data.IP.RouteTable.Internal
@@ -29,15 +30,10 @@
     arbitrary = arbitraryAdr toIPv6 65535 8
 
 arbitraryAdr :: Routable a => ([Int] -> a) -> Int -> Int -> Gen a
-arbitraryAdr func width adrlen = do
-    a <- replicateM adrlen (choose (0, width))
-    return $ func a
+arbitraryAdr func width adrlen = func <$> replicateM adrlen (choose (0, width))
 
 arbitraryIP :: Routable a => Gen a -> Int -> Gen (AddrRange a)
-arbitraryIP adrGen msklen = do
-    adr <- adrGen
-    len <- choose (0,msklen)
-    return $ makeAddrRange adr len
+arbitraryIP adrGen msklen = makeAddrRange <$> adrGen <*> choose (0,msklen)
 
 ----------------------------------------------------------------
 --
