diff --git a/Data/BoundingBox.hs b/Data/BoundingBox.hs
new file mode 100644
--- /dev/null
+++ b/Data/BoundingBox.hs
@@ -0,0 +1,63 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.BoundingBox
+-- Copyright   :  (C) 2014 Fumiaki Kinoshita
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Fumiaki Kinoshita <fumiexcel@gmail.com>
+-- Stability   :  provisional
+-- Portability :  non-portable
+-- The type and accessors for bounding boxes
+----------------------------------------------------------------------------
+{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, Rank2Types #-}
+module Data.BoundingBox where
+
+import Control.Lens
+import Data.Foldable
+import Data.Typeable
+import Control.Applicative
+import Data.Foldable as Foldable
+import Data.Traversable as Traversable
+
+-- | The type of bounding box for arbitrary vector @f@.
+data Box f a = Box (f a) (f a) deriving (Show, Eq, Ord, Functor, Foldable, Traversable, Read)
+
+instance Applicative f => Applicative (Box f) where
+    pure a = Box (pure a) (pure a)
+    {-# INLINE pure #-}
+    Box f g <*> Box a b = Box (f <*> a) (g <*> b)
+    {-# INLINE (<*>) #-}
+
+instance Monad f => Monad (Box f) where
+    return a = Box (return a) (return a)
+    {-# INLINE return #-}
+    Box f g >>= k = Box (f >>= \x -> let Box p _ = k x in p) (g >>= \x -> let Box _ q = k x in q)
+
+-- | check whether the point is in the box.
+isInside :: (Applicative f, Foldable f, Ord a) => f a -> Box f a -> Bool
+isInside v (Box p q) = Foldable.and (liftA2 (<=) p v) && Foldable.and (liftA2 (<=) v q)
+
+-- | Returns True if the bounding box is valid.
+isCanonical :: (Applicative f, Foldable f, Ord a) => Box f a -> Bool
+isCanonical (Box p q) = Foldable.and (liftA2 (<=) p q)
+
+-- | Calculate an intersect between two boundingboxes.
+intersect :: (Applicative f, Ord a) => Box f a -> Box f a -> Box f a
+intersect (Box p q) (Box r s) = Box (liftA2 max p r) (liftA2 min q s)
+
+-- | Enumerate the corners.
+corners :: (Applicative f, Traversable f) => Box f a -> [f a]
+corners (Box p q) = Traversable.sequence $ liftA2 (\a b -> [a, b]) p q
+
+sizePos :: (Applicative f, Num a) => f a -> Iso' (Box f a) (f a, f a)
+sizePos k = iso f g where
+    f (Box p q) = (liftA2 (-) q p, (+) <$> liftA2 (*) (fmap (1-) k) p <*> liftA2 (*) k q)
+    g (s, v) = Box ((-) <$> v <*> liftA2 (*) k s) ((+) <$> v <*> liftA2 (*) (fmap (1-) k) s)
+
+-- | The accessor for the position on the given reference. Usually the reference point 
+position :: (Applicative f, Num a) => f a -> Lens' (Box f a) (f a)
+position ref = sizePos ref . _2
+
+-- | The accessor for the size. A given reference point will be a center of resizing.
+size :: (Applicative f, Num a) => f a -> Lens' (Box f a) (f a)
+size ref = sizePos ref . _1
diff --git a/Data/BoundingBox/Dim2.hs b/Data/BoundingBox/Dim2.hs
deleted file mode 100644
--- a/Data/BoundingBox/Dim2.hs
+++ /dev/null
@@ -1,114 +0,0 @@
-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveDataTypeable, Rank2Types #-}
------------------------------------------------------------------------------
--- |
--- Module      :  Data.BoundingBox.Dim2
--- Copyright   :  (C) 2014 Fumiaki Kinoshita
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Fumiaki Kinoshita <fumiexcel@gmail.com>
--- Stability   :  provisional
--- Portability :  non-portable
--- The type and accessors for 2D bounding boxes
-----------------------------------------------------------------------------
-module Data.BoundingBox.Dim2 (
-    BoundingBox(..)
-    , inBoundingBox
-    , intersect
-    , enclose
-    , _TLBR
-    , _BLTR
-    , _Corners
-    , Reference(..)
-    , sizePos
-    , position
-    , size
-    ) where
-
-import Linear
-import Control.Lens
-import Data.Foldable
-import Data.Typeable
-import Control.Applicative
-
-data BoundingBox a = BoundingBox !a !a !a !a deriving (Show, Eq, Ord, Functor, Foldable, Traversable, Read, Typeable)
-
-instance Applicative BoundingBox where
-    pure a = BoundingBox a a a a
-    BoundingBox f0 g0 f1 g1 <*> BoundingBox x0 y0 x1 y1 = BoundingBox (f0 x0) (g0 y0) (f1 x1) (g1 y1)
-
--- | Determine whether the given point is in the 'BoundingBox'.
-inBoundingBox :: Ord a => V2 a -> BoundingBox a -> Bool
-inBoundingBox (V2 x y) (BoundingBox x0 y0 x1 y1) = x0 <= x && x <= x1 && y0 <= y && y <= y1
-
--- | Intersection between two boundingboxes.
-intersect :: Ord a => BoundingBox a -> BoundingBox a -> Maybe (BoundingBox a)
-intersect (BoundingBox x0 y0 x1 y1) (BoundingBox x2 y2 x3 y3)
-    | x4 > x5 = Nothing
-    | y4 > y5 = Nothing
-    | otherwise = Just $ BoundingBox x4 y4 x5 y5
-    where
-        x4 = max x0 x2
-        y4 = max y0 y2
-        x5 = min x1 x3
-        y5 = min y1 y3
-
-enclose :: (Num a, Ord a) => V2 a -> BoundingBox a -> BoundingBox a
-enclose (V2 x y) (BoundingBox x0 y0 x1 y1) = BoundingBox (min x x0) (min y y0) (max x x1) (max y y1)
-
--- | The type of reference points.
--- @
--- TL--T--TR
--- |       |
--- L   C   R
--- |       |
--- BL--B--BR
--- @
-data Reference = TL | T | TR
-               |  L | C | R
-               | BL | B | BR
-    deriving (Show, Eq, Ord, Read, Enum, Bounded)
-
--- |
--- @
--- fst----+
---  |     |
---  +----snd
--- @
-_TLBR :: Iso' (BoundingBox a) (V2 a, V2 a)
-_TLBR = iso (\(BoundingBox x0 y0 x1 y1) -> (V2 x0 y0, V2 x1 y1)) (\(V2 x0 y0, V2 x1 y1) -> BoundingBox x0 y0 x1 y1)
-
--- |
--- @
---  +----snd
---  |     |
--- fst----+
--- @
-_BLTR :: Iso' (BoundingBox a) (V2 a, V2 a)
-_BLTR = iso (\(BoundingBox x0 y0 x1 y1) -> (V2 x0 y1, V2 x1 y0)) (\(V2 x0 y1, V2 x1 y0) -> BoundingBox x0 y0 x1 y1)
-
-sizePos :: Fractional a => Reference -> Iso' (BoundingBox a) (V2 a, V2 a)
-sizePos ref = iso f g where
-    f (BoundingBox x0 y0 x1 y1) = (V2 (x1 - x0) (y1 - y0), V2 x0 y0 * (1 - k) + V2 x1 y1 * k)
-    g (s@(V2 w h), p) = BoundingBox x0 y0 x1 y1 where
-        V2 x0 y0 = p - k * s
-        V2 x1 y1 = p + (1 - k) * s
-    k = case ref of
-        TL -> V2 0 0
-        T -> V2 0.5 0
-        TR -> V2 1 0
-        L -> V2 0 0.5
-        C -> V2 0.5 0.5
-        R -> V2 1 0.5
-        BL -> V2 0 1
-        B -> V2 0.5 1
-        BR -> V2 1 1
-
-_Corners :: Traversal' (BoundingBox a) (V2 a)
-_Corners f (BoundingBox x0 y0 x1 y1) = go <$> f (V2 x0 y0) <*> f (V2 x1 y0) <*> f (V2 x1 y1) <*> f (V2 x0 y1) where
-    go (V2 x0' _) (V2 _ y1') (V2 x2' _) (V2 _ y3') = BoundingBox x0' y1' x2' y3'
-
-position :: Fractional a => Reference -> Lens' (BoundingBox a) (V2 a)
-position ref = sizePos ref . _2
-
-size :: Fractional a => Reference -> Lens' (BoundingBox a) (V2 a)
-size ref = sizePos ref . _1
diff --git a/boundingboxes.cabal b/boundingboxes.cabal
--- a/boundingboxes.cabal
+++ b/boundingboxes.cabal
@@ -1,5 +1,5 @@
 name:                boundingboxes
-version:             0.1.1
+version:             0.2
 synopsis:            The type for 2D bounding box
 -- description:         
 homepage:            https://github.com/fumieval/boundingboxes
@@ -14,10 +14,10 @@
 cabal-version:       >=1.10
 
 library
-  exposed-modules:     Data.BoundingBox.Dim2
+  exposed-modules:     Data.BoundingBox
   -- other-modules:       
   other-extensions:    DeriveFunctor, DeriveFoldable, DeriveTraversable, DeriveDataTypeable, Rank2Types
-  build-depends:       base == 4.*, linear >= 1.0, lens >= 3.8 && < 5
+  build-depends:       base == 4.*, lens >= 3.8 && < 5
   -- hs-source-dirs:      
   default-language:    Haskell2010
 
@@ -34,4 +34,4 @@
     , random
     , boundingboxes
   main-is: properties.hs
-  hs-source-dirs: tests
+  hs-source-dirs: tests
diff --git a/tests/properties.hs b/tests/properties.hs
--- a/tests/properties.hs
+++ b/tests/properties.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE TemplateHaskell, ViewPatterns #-}
-import Data.BoundingBox.Dim2
+{-# LANGUAGE TemplateHaskell, ViewPatterns, FlexibleInstances #-}
+import Data.BoundingBox
 import Test.QuickCheck
 import Test.Framework.Providers.QuickCheck2
 import Test.Framework.TH
@@ -8,32 +8,31 @@
 import Control.Applicative
 import System.Random
 
-instance (Num a, Random a) => Arbitrary (BoundingBox a) where
+instance (Num a, Random a) => Arbitrary (Box V2 a) where
     arbitrary = sized $ \n -> let k = fromIntegral n in do
         x0 <- choose (-k, 0)
         y0 <- choose (-k, 0)
         x1 <- choose (0, k)
         y1 <- choose (0, k)
-        return (BoundingBox x0 y0 x1 y1)
+        return (Box (V2 x0 y0) (V2 x1 y1))
 
+newtype Reference = Reference { getReference :: V2 Float } deriving Show
+
 instance Arbitrary Reference where
-    arbitrary = toEnum <$> choose (0, 8)
+    arbitrary = fmap Reference $ V2 <$> oneof [pure 0, pure 0.5, pure 1] <*> oneof [pure 0, pure 0.5, pure 1]
 
 instance Arbitrary a => Arbitrary (V2 a) where
     arbitrary = V2 <$> arbitrary <*> arbitrary
 
-prop_resize bb ref sz = nearZero $ bb ^. position ref - bb' ^. position ref where
-    bb' = bb & size ref .~ getPositive sz :: BoundingBox Float
+prop_resize bb (getReference -> ref) sz = nearZero $ bb ^. position ref - bb' ^. position ref where
+    bb' = bb & size ref .~ getPositive sz :: Box V2 Float
 
-prop_rearrange ref bb pos = nearZero $ bb ^. size C - bb' ^. size C where
-    bb' = bb & position ref .~ pos :: BoundingBox Float
+prop_rearrange (getReference -> ref) bb pos = nearZero $ bb ^. size 0 - bb' ^. size 0 where
+    bb' = bb & position ref .~ pos :: Box V2 Float
 
-prop_construct ref pos (getPositive -> sz) = nearZero (bb ^. size C - sz)
+prop_construct (getReference -> ref) pos (getPositive -> sz) = nearZero (bb ^. size 0 - sz)
     .&&. nearZero (bb ^. position ref - pos) where
     
-    bb = sizePos ref # (sz, pos) :: BoundingBox Float
-
-prop_enclosure xs = and [inBoundingBox p (foldr enclose (pure 0) ps) | p <- ps] where
-    ps = map (uncurry V2) xs :: [V2 Float]
+    bb = sizePos ref # (sz, pos) :: Box V2 Float
 
 main = $(defaultMainGenerator)
