diff --git a/bitvec.cabal b/bitvec.cabal
--- a/bitvec.cabal
+++ b/bitvec.cabal
@@ -1,28 +1,28 @@
 name: bitvec
-version: 0.1.1.0
+version: 0.2.0.0
 cabal-version: >=1.10
 build-type: Simple
 license: PublicDomain
 license-file: LICENSE
 maintainer: Andrew Lelechenko <andrew.lelechenko@gmail.com>
 homepage: https://github.com/Bodigrim/bitvec
-synopsis: Unboxed vectors of bits / dense IntSets
+synopsis: Unboxed bit vectors
 description:
-  Another bit-array library for Haskell.  This one defines a `Bit`
-  type (which is an instance of all the "expected" classes, including
-  numeric ones) and makes that type an instance of `Data.Vector.Unboxed.
-  Unbox`, so we get a lot of nice APIs for free.  `Bool` is already an
-  unboxable type, but the current unboxed `Vector` implementation packs
-  each bit as a byte.  This one packs 8 bits per byte, as expected
-  (`UArray` from the `array` package also uses one bit per `Bool`).
-  .
-  In addition to the `Vector` interface, there are several high-level
-  operations and some low-level ones suitable for building new bulk
-  operations by viewing the bit-vector as a word vector.
+  Bit vectors library for Haskell.
+
+  The current @vector@ package represents unboxed arrays of @Bool@
+  allocating one byte per boolean, which might be considered wasteful.
+  This library provides a newtype wrapper @Bit@ and a custom instance
+  of unboxed @Vector@, which packs booleans densely.
+  It is a time-memory tradeoff: 8x less memory footprint
+  at the price of moderate performance penalty
+  (mostly, for random writes).
 category: Data, Bit Vectors
 author: James Cook <mokus@deepbondi.net>,
         Andrew Lelechenko <andrew.lelechenko@gmail.com>
 tested-with: GHC ==8.0.2 GHC ==8.2.2 GHC ==8.4.3 GHC ==8.6.3
+extra-source-files:
+  changelog.md
 
 source-repository head
   type: git
@@ -30,25 +30,25 @@
 
 library
   exposed-modules:
-      Data.Bit
-      Data.Vector.Unboxed.Bit
-      Data.Vector.Unboxed.Mutable.Bit
+    Data.Bit
+    Data.Vector.Unboxed.Bit
+    Data.Vector.Unboxed.Mutable.Bit
   build-depends:
-      base >=3 && <5,
-      primitive -any,
-      vector >=0.8
+    base >=4.8 && <5,
+    primitive -any,
+    vector >=0.8
   default-language: Haskell2010
   hs-source-dirs: src
   other-modules:
-      Data.Bit.Internal
-      Data.Vector.Unboxed.Bit.Internal
+    Data.Bit.Internal
+    Data.Vector.Unboxed.Bit.Internal
   ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-type-defaults
 
 test-suite bitvec-tests
   type: exitcode-stdio-1.0
   main-is: Main.hs
   build-depends:
-    base >=3,
+    base >=4.8 && <5,
     bitvec -any,
     HUnit -any,
     primitive -any,
@@ -62,7 +62,6 @@
   hs-source-dirs: test
   other-modules:
     Support
-    Tests.Bit
     Tests.MVector
     Tests.SetOps
     Tests.Vector
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,11 @@
+# 0.2.0.0
+
+* Remove hand-written 'Num', 'Real', 'Integral', 'Bits' instances.
+* Derive 'Bits' and 'FiniteBits' instances.
+* Expose 'Bit' constructor directly and remove 'fromBool' function.
+* Rename 'toBool' to 'unBit'.
+
+# 0.1.1.0
+
+* Fix bugs in `MVector` and `Vector` instances of `Bit`.
+* Speed up `MVector` and `Vector` instances of `Bit`.
diff --git a/src/Data/Bit.hs b/src/Data/Bit.hs
--- a/src/Data/Bit.hs
+++ b/src/Data/Bit.hs
@@ -1,93 +1,6 @@
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy #-}
-#else
-#define safe
-#endif
-
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-
 module Data.Bit
-     ( Bit
-     , fromBool
-     , toBool
-     ) where
+    ( Bit(..)
+    ) where
 
-import safe Data.Bit.Internal
-import safe Data.Bits
+import Data.Bit.Internal
 import Data.Vector.Unboxed.Bit.Internal ({- instance Unbox Bit -})
-
-instance Show Bit where
-    showsPrec _ (Bit False) = showString "0"
-    showsPrec _ (Bit True ) = showString "1"
-instance Read Bit where
-    readsPrec _ ('0':rest) = [(0, rest)]
-    readsPrec _ ('1':rest) = [(1, rest)]
-    readsPrec _ _ = []
-
-
-liftBool2 :: (Bool -> Bool -> Bool) -> (Bit -> Bit -> Bit)
-liftBool2 op x y = fromBool (toBool x `op` toBool y)
-liftInt2  :: (Int -> Int -> Int) -> (Bit -> Bit -> Bit)
-liftInt2  op x y = fromIntegral (fromIntegral x `op` fromIntegral y)
-
--- | The 'Num' instance is currently based on integers mod 2, so (+) and (-) are
--- XOR, (*) is AND, and all the unary operations are identities.  Saturating
--- operations would also be a sensible alternative.
-instance Num Bit where
-    fromInteger = fromBool . odd
-    (+) = liftInt2 (+)
-    (-) = liftInt2 (-)
-    (*) = liftInt2 (*)
-    abs = id
-    signum = id
-
-instance Real Bit where
-    toRational (Bit False) = 0
-    toRational (Bit True ) = 1
-
-instance Integral Bit where
-    quotRem _ (Bit False) = error "divide by zero"
-    quotRem x (Bit True ) = (x, 0)
-
-    divMod = quotRem
-    toInteger (Bit False) = 0
-    toInteger (Bit True ) = 1
-
-instance Bits Bit where
-    (.&.) = liftBool2 (&&)
-    (.|.) = liftBool2 (||)
-    xor = liftBool2 (/=)
-
-    complement (Bit x) = Bit (not x)
-
-    shift b 0 = b
-    shift _ _ = 0
-
-    rotate = const
-
-    bit 0 = 1
-    bit _ = 0
-
-    setBit _ 0 = 1
-    setBit b _ = b
-
-    clearBit _ 0 = 0
-    clearBit b _ = b
-
-    complementBit b 0 = complement b
-    complementBit b _ = b
-
-    testBit b 0 = toBool b
-    testBit _ _ = False
-
-    bitSizeMaybe _ = Just 1
-    bitSize _ = 1
-
-    isSigned _ = False
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
-
-    popCount = fromEnum
-
-#endif
diff --git a/src/Data/Bit/Internal.hs b/src/Data/Bit/Internal.hs
--- a/src/Data/Bit/Internal.hs
+++ b/src/Data/Bit/Internal.hs
@@ -1,36 +1,40 @@
-{-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE BangPatterns               #-}
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#else
-#define safe
-#endif
-module Data.Bit.Internal where
-
-import safe Data.Bits
-import safe Data.List
-import safe Data.Typeable
-
-#if !MIN_VERSION_base(4,3,0)
-import safe Control.Monad
-
-mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
-mfilter p xs = do x <- xs; guard (p x); return x
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
-#endif
+module Data.Bit.Internal where
 
+import Data.Bits
+import Data.List
+import Data.Typeable
 
-newtype Bit = Bit { toBool :: Bool }
-    deriving (Bounded, Eq, Ord, Typeable)
+-- | A newtype wrapper with a custom instance
+-- of "Data.Vector.Unboxed", which packs booleans
+-- as efficient as possible (8 values per byte).
+-- Vectors of `Bit` use 8x less memory
+-- than vectors of 'Bool' (which stores one value per byte),
+-- but random writes
+-- are slightly slower.
+--
+-- In addition to "Data.Vector.Unboxed" interface,
+-- one can also find assorted utilities
+-- from "Data.Vector.Unboxed.Bit"
+-- and "Data.Vector.Unboxed.Mutable.Bit".
+newtype Bit = Bit { unBit :: Bool }
+    deriving (Bounded, Enum, Eq, Ord, FiniteBits, Bits, Typeable)
 
 fromBool :: Bool -> Bit
-fromBool b  = Bit b
+fromBool b = Bit b
 
-instance Enum Bit where
-    toEnum      = fromBool . toEnum
-    fromEnum    = fromEnum . toBool
+instance Show Bit where
+    showsPrec _ (Bit False) = showString "0"
+    showsPrec _ (Bit True ) = showString "1"
 
+instance Read Bit where
+    readsPrec _ ('0':rest) = [(Bit False, rest)]
+    readsPrec _ ('1':rest) = [(Bit False, rest)]
+    readsPrec _ _ = []
+
 -- various internal utility functions and constants
 
 lg2 :: Int -> Int
@@ -154,16 +158,6 @@
 
 diff :: Word -> Word -> Word
 diff w1 w2 = w1 .&. complement w2
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 704
-
-popCount :: Bits a => a -> Int
-popCount = loop 0
-    where
-        loop !n 0 = n
-        loop !n x = loop (n+1) (x .&. (x - 1))
-
-#endif
 
 ffs :: Word -> Maybe Int
 ffs 0 = Nothing
diff --git a/src/Data/Vector/Unboxed/Bit.hs b/src/Data/Vector/Unboxed/Bit.hs
--- a/src/Data/Vector/Unboxed/Bit.hs
+++ b/src/Data/Vector/Unboxed/Bit.hs
@@ -1,16 +1,8 @@
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE BangPatterns               #-}
-{-# LANGUAGE CPP #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy #-}
-#else
-#define safe
-#endif
-module Data.Vector.Unboxed.Bit
-     ( module Data.Bit
-     , module U
 
-     , wordSize
+module Data.Vector.Unboxed.Bit
+     ( wordSize
      , wordLength
      , fromWords
      , toWords
@@ -54,21 +46,20 @@
      , findIndex
      ) where
 
-import safe           Control.Monad
-import                Control.Monad.ST
-import safe           Data.Bit
-import safe           Data.Bit.Internal
-import safe           Data.Bits
-import safe qualified Data.List                          as L
-import      qualified Data.Vector.Generic                as V
-import      qualified Data.Vector.Generic.Mutable        as MV
-import                Data.Vector.Unboxed                as U
+import           Control.Monad
+import           Control.Monad.ST
+import           Data.Bit.Internal
+import           Data.Bits
+import qualified Data.List                          as L
+import qualified Data.Vector.Generic                as V
+import qualified Data.Vector.Generic.Mutable        as MV
+import           Data.Vector.Unboxed                as U
     hiding (and, or, any, all, reverse, findIndex)
-import      qualified Data.Vector.Unboxed                as Unsafe
-import safe qualified Data.Vector.Unboxed.Mutable.Bit    as B
-import                Data.Vector.Unboxed.Bit.Internal
-import safe           Data.Word
-import safe           Prelude                            as P
+import qualified Data.Vector.Unboxed                as Unsafe
+import qualified Data.Vector.Unboxed.Mutable.Bit    as B
+import           Data.Vector.Unboxed.Bit.Internal
+import           Data.Word
+import           Prelude                            as P
     hiding (and, or, any, all, reverse)
 
 wordLength :: U.Vector Bit -> Int
@@ -145,9 +136,9 @@
         n = min (V.length is) (V.length xs)
 
         next j
-            | j >= n             = Nothing
-            | toBool (is V.! j)  = Just (xs V.! j, j + 1)
-            | otherwise          = next           (j + 1)
+            | j >= n           = Nothing
+            | unBit (is V.! j) = Just (xs V.! j, j + 1)
+            | otherwise        = next           (j + 1)
 
 -- | Given a vector of bits and a vector of things, extract those things for which the corresponding bit is unset.
 --
@@ -158,9 +149,9 @@
         n = min (V.length is) (V.length xs)
 
         next j
-            | j >= n             = Nothing
-            | toBool (is V.! j)  = next           (j + 1)
-            | otherwise          = Just (xs V.! j, j + 1)
+            | j >= n           = Nothing
+            | unBit (is V.! j) = next           (j + 1)
+            | otherwise        = Just (xs V.! j, j + 1)
 
 selectBits :: U.Vector Bit -> U.Vector Bit -> U.Vector Bit
 selectBits is xs = runST $ do
@@ -213,17 +204,17 @@
                         || loop (i + wordSize)
 
 all :: (Bit -> Bool) -> Vector Bit -> Bool
-all p = case (p 0, p 1) of
+all p = case (p (Bit False), p (Bit True)) of
     (False, False) -> U.null
-    (False,  True) -> allBits 1
-    (True,  False) -> allBits 0
+    (False,  True) -> allBits (Bit True)
+    (True,  False) -> allBits (Bit False)
     (True,   True) -> flip seq True
 
 any :: (Bit -> Bool) -> Vector Bit -> Bool
-any p = case (p 0, p 1) of
+any p = case (p (Bit False), p (Bit True)) of
     (False, False) -> flip seq False
-    (False,  True) -> anyBits 1
-    (True,  False) -> anyBits 0
+    (False,  True) -> anyBits (Bit True)
+    (True,  False) -> anyBits (Bit False)
     (True,   True) -> not . U.null
 
 allBits, anyBits :: Bit -> U.Vector Bit -> Bool
@@ -246,7 +237,7 @@
 first b xs = mfilter (< n) (loop 0)
     where
         !n = V.length xs
-        !ff | toBool b  = ffs
+        !ff | unBit b   = ffs
             | otherwise = ffs . complement
 
         loop !i
@@ -254,8 +245,8 @@
             | otherwise = fmap (i +) (ff (indexWord xs i)) `mplus` loop (i + wordSize)
 
 findIndex :: (Bit -> Bool) -> Vector Bit -> Maybe Int
-findIndex p xs = case (p 0, p 1) of
+findIndex p xs = case (p (Bit False), p (Bit True)) of
     (False, False) -> Nothing
-    (False,  True) -> first 1 xs
-    (True,  False) -> first 0 xs
+    (False,  True) -> first (Bit True)  xs
+    (True,  False) -> first (Bit False) xs
     (True,   True) -> if V.null xs then Nothing else Just 0
diff --git a/src/Data/Vector/Unboxed/Bit/Internal.hs b/src/Data/Vector/Unboxed/Bit/Internal.hs
--- a/src/Data/Vector/Unboxed/Bit/Internal.hs
+++ b/src/Data/Vector/Unboxed/Bit/Internal.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE BangPatterns          #-}
-{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies          #-}
 {-# LANGUAGE ViewPatterns          #-}
@@ -118,7 +117,6 @@
 hiMask n = complement (1 `shiftL` n - 1)
 
 instance MV.MVector U.MVector Bit where
-#if MIN_VERSION_vector(0,11,0)
     {-# INLINE basicInitialize #-}
     basicInitialize (BitMVec _ 0 _) = pure ()
     basicInitialize (BitMVec 0 n v) = case modWordSize n of
@@ -141,7 +139,6 @@
                     MV.basicInitialize (MV.slice 1 (vLen - 2) v)
                     MV.modify v (\val -> val .&. loMask s) 0
                     MV.modify v (\val -> val .&. hiMask nMod) (vLen - 1)
-#endif
 
     {-# INLINE basicUnsafeNew #-}
     basicUnsafeNew       n   = liftM (BitMVec 0 n) (MV.basicUnsafeNew       (nWords n))
diff --git a/src/Data/Vector/Unboxed/Mutable/Bit.hs b/src/Data/Vector/Unboxed/Mutable/Bit.hs
--- a/src/Data/Vector/Unboxed/Mutable/Bit.hs
+++ b/src/Data/Vector/Unboxed/Mutable/Bit.hs
@@ -1,16 +1,8 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE BangPatterns               #-}
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy #-}
-#else
-#define safe
-#endif
-module Data.Vector.Unboxed.Mutable.Bit
-     ( module Data.Bit
-     , module U
 
-     , wordSize
+module Data.Vector.Unboxed.Mutable.Bit
+     ( wordSize
      , wordLength
      , cloneFromWords
      , cloneToWords
@@ -46,18 +38,17 @@
      , reverseInPlace
      ) where
 
-import safe           Control.Monad
-import                Control.Monad.Primitive
-import safe           Data.Bit
-import safe           Data.Bit.Internal
-import safe           Data.Bits
-import      qualified Data.Vector.Generic.Mutable       as MV
-import      qualified Data.Vector.Generic               as V
-import      qualified Data.Vector.Unboxed               as U (Vector)
-import                Data.Vector.Unboxed.Mutable       as U
-import                Data.Vector.Unboxed.Bit.Internal
-import safe           Data.Word
-import safe           Prelude                           as P
+import           Control.Monad
+import           Control.Monad.Primitive
+import           Data.Bit.Internal
+import           Data.Bits
+import qualified Data.Vector.Generic.Mutable       as MV
+import qualified Data.Vector.Generic               as V
+import qualified Data.Vector.Unboxed               as U (Vector)
+import           Data.Vector.Unboxed.Mutable       as U
+import           Data.Vector.Unboxed.Bit.Internal
+import           Data.Word
+import           Prelude                           as P
     hiding (and, or, any, all, reverse)
 
 
@@ -247,17 +238,17 @@
                     else loop (i + wordSize)
 
 all :: PrimMonad m => (Bit -> Bool) -> U.MVector (PrimState m) Bit -> m Bool
-all p = case (p 0, p 1) of
+all p = case (p (Bit False), p (Bit True)) of
     (False, False) -> return . MV.null
-    (False,  True) -> allBits 1
-    (True,  False) -> allBits 0
+    (False,  True) -> allBits (Bit True)
+    (True,  False) -> allBits (Bit False)
     (True,   True) -> flip seq (return True)
 
 any :: PrimMonad m => (Bit -> Bool) -> U.MVector (PrimState m) Bit -> m Bool
-any p = case (p 0, p 1) of
+any p = case (p (Bit False), p (Bit True)) of
     (False, False) -> flip seq (return False)
-    (False,  True) -> anyBits 1
-    (True,  False) -> anyBits 0
+    (False,  True) -> anyBits (Bit True)
+    (True,  False) -> anyBits (Bit False)
     (True,   True) -> return . not . MV.null
 
 allBits, anyBits :: PrimMonad m => Bit -> U.MVector (PrimState m) Bit -> m Bool
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -3,15 +3,13 @@
 
 import Test.Framework (defaultMain)
 
-import Tests.Bit (bitTests)
 import Tests.SetOps (setOpTests)
 import Tests.MVector (mvectorTests)
 import Tests.Vector (vectorTests)
 
 main :: IO ()
 main = defaultMain
-    [ bitTests
-    , mvectorTests
+    [ mvectorTests
     , setOpTests
     , vectorTests
     ]
diff --git a/test/Support.hs b/test/Support.hs
--- a/test/Support.hs
+++ b/test/Support.hs
@@ -17,14 +17,14 @@
 import Test.QuickCheck
 
 instance Arbitrary Bit where
-    arbitrary = fromBool <$> arbitrary
-    shrink = fmap fromBool . shrink . toBool
+    arbitrary = Bit <$> arbitrary
+    shrink = fmap Bit . shrink . unBit
 
 instance CoArbitrary Bit where
-    coarbitrary = coarbitrary . toBool
+    coarbitrary = coarbitrary . unBit
 
 instance Function Bit where
-    function f = functionMap toBool fromBool f
+    function f = functionMap unBit Bit f
 
 instance (Arbitrary a, U.Unbox a) => Arbitrary (U.Vector a) where
     arbitrary = V.new <$> arbitrary
@@ -64,14 +64,14 @@
         loop _ w [] = (w, [])
         loop i w (x:xs)
             | i >= wordSize = (w, x:xs)
-            | otherwise     = loop (i+1) (if toBool x then setBit w i else w) xs
+            | otherwise     = loop (i+1) (if unBit x then setBit w i else w) xs
 
 readWordL :: [Bit] -> Int -> Word
 readWordL xs 0 = fst (packBitsToWord xs)
 readWordL xs n = readWordL (drop n xs) 0
 
 wordToBitList :: Word -> [Bit]
-wordToBitList w = [ fromBool (testBit w i) | i <- [0 .. wordSize - 1] ]
+wordToBitList w = [ Bit (testBit w i) | i <- [0 .. wordSize - 1] ]
 
 writeWordL :: [Bit] -> Int -> Word -> [Bit]
 writeWordL xs 0 w = zipWith const (wordToBitList w) xs ++ drop wordSize xs
diff --git a/test/Tests/Bit.hs b/test/Tests/Bit.hs
deleted file mode 100644
--- a/test/Tests/Bit.hs
+++ /dev/null
@@ -1,53 +0,0 @@
-module Tests.Bit where
-
-import Data.Bit
-import Data.Bits
-import Test.HUnit ((@?=))
-import Test.Framework (Test, testGroup)
-import Test.Framework.Providers.HUnit (testCase)
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-
-b0 :: Bit
-b0 = 0
-
-b1 :: Bit
-b1 = 1
-
-testOp :: (Eq a, Show a) => String -> (Bit -> a) -> (Bit -> a) -> [Test]
-testOp opName op rOp =
-    [ testCase (unwords [opName, show x])
-        (op x @?= rOp x)
-    | x <- [0, 1 :: Bit]
-    ]
-
-testBinop :: (Eq a, Show a) => String -> (Bit -> Bit -> a) -> (Bit -> Bit -> a) -> [Test]
-testBinop opName op rOp =
-    [ testCase (unwords [show x, opName, show y])
-        (op x y @?= rOp x y)
-    | x <- [0, 1 :: Bit]
-    , y <- [0, 1 :: Bit]
-    ]
-
-bitTests :: Test
-bitTests = testGroup "Data.Bit"
-    [ testGroup "basic assertions"
-        [ testCase "toBool 0"       (toBool 0       @?= False)
-        , testCase "toBool 1"       (toBool 1       @?= True)
-        , testCase "fromBool False" (fromBool False @?= 0)
-        , testCase "fromBool True"  (fromBool True  @?= 1)
-        , testCase "fromInteger 0"  (fromInteger 0  @?= (0 :: Bit))
-        , testCase "fromInteger 1"  (fromInteger 1  @?= (1 :: Bit))
-        ]
-    , testGroup "Num instance forms ℤ/2" $ concat
-        [ [ testProperty "fromInteger == odd" prop_fromInteger ]
-        , testBinop "+" (+) xor
-        , testBinop "*" (*) (.&.)
-        , testBinop "-" (+) xor
-        , testOp "negate" negate id
-        , testOp "abs"    abs    id
-        , testOp "signum" signum id
-        ]
-    ]
-
-prop_fromInteger :: Integer -> Bool
-prop_fromInteger x = fromInteger x == fromBool (odd x)
diff --git a/test/Tests/MVector.hs b/test/Tests/MVector.hs
--- a/test/Tests/MVector.hs
+++ b/test/Tests/MVector.hs
@@ -10,7 +10,8 @@
 import qualified Data.Vector.Generic             as V
 import qualified Data.Vector.Generic.Mutable     as M (basicInitialize, basicSet)
 import qualified Data.Vector.Generic.New         as N
-import qualified Data.Vector.Unboxed.Bit         as B
+import qualified Data.Vector.Unboxed.Bit         as B hiding (reverse)
+import qualified Data.Vector.Unboxed             as B
 import qualified Data.Vector.Unboxed.Mutable.Bit as U
 import qualified Data.Vector.Unboxed.Mutable     as M
 import Test.Framework (Test, testGroup)
@@ -60,124 +61,124 @@
     ]
 
 case_write_init_read1 :: IO ()
-case_write_init_read1 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_init_read1 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 0 (fromBool True)
+    M.write arr 0 (Bit True)
     M.basicInitialize (M.slice 1 1 arr)
     M.read arr 0
 
 case_write_init_read2 :: IO ()
-case_write_init_read2 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_init_read2 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 1 (fromBool True)
+    M.write arr 1 (Bit True)
     M.basicInitialize (M.slice 0 1 arr)
     M.read arr 1
 
 case_write_init_read3 :: IO ()
-case_write_init_read3 = assertEqual "should be equal" (fromBool True, fromBool True) $ runST $ do
+case_write_init_read3 = assertEqual "should be equal" (Bit True, Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 0 (fromBool True)
-    M.write arr 1 (fromBool True)
+    M.write arr 0 (Bit True)
+    M.write arr 1 (Bit True)
     M.basicInitialize (M.slice 1 0 arr)
     (,) <$> M.read arr 0 <*> M.read arr 1
 
 case_write_init_read4 :: IO ()
-case_write_init_read4 = assertEqual "should be equal" (fromBool True, fromBool True) $ runST $ do
+case_write_init_read4 = assertEqual "should be equal" (Bit True, Bit True) $ runST $ do
     arr <- M.new 3
-    M.write arr 0 (fromBool True)
-    M.write arr 2 (fromBool True)
+    M.write arr 0 (Bit True)
+    M.write arr 2 (Bit True)
     M.basicInitialize (M.slice 1 1 arr)
     (,) <$> M.read arr 0 <*> M.read arr 2
 
 case_write_set_read1 :: IO ()
-case_write_set_read1 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_set_read1 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 0 (fromBool True)
-    M.basicSet (M.slice 1 1 arr) (fromBool False)
+    M.write arr 0 (Bit True)
+    M.basicSet (M.slice 1 1 arr) (Bit False)
     M.read arr 0
 
 case_write_set_read2 :: IO ()
-case_write_set_read2 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_set_read2 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 1 (fromBool True)
-    M.basicSet (M.slice 0 1 arr) (fromBool False)
+    M.write arr 1 (Bit True)
+    M.basicSet (M.slice 0 1 arr) (Bit False)
     M.read arr 1
 
 case_write_set_read3 :: IO ()
-case_write_set_read3 = assertEqual "should be equal" (fromBool True, fromBool True) $ runST $ do
+case_write_set_read3 = assertEqual "should be equal" (Bit True, Bit True) $ runST $ do
     arr <- M.new 2
-    M.write arr 0 (fromBool True)
-    M.write arr 1 (fromBool True)
-    M.basicSet (M.slice 1 0 arr) (fromBool False)
+    M.write arr 0 (Bit True)
+    M.write arr 1 (Bit True)
+    M.basicSet (M.slice 1 0 arr) (Bit False)
     (,) <$> M.read arr 0 <*> M.read arr 1
 
 case_write_set_read4 :: IO ()
-case_write_set_read4 = assertEqual "should be equal" (fromBool True, fromBool True) $ runST $ do
+case_write_set_read4 = assertEqual "should be equal" (Bit True, Bit True) $ runST $ do
     arr <- M.new 3
-    M.write arr 0 (fromBool True)
-    M.write arr 2 (fromBool True)
-    M.basicSet (M.slice 1 1 arr) (fromBool False)
+    M.write arr 0 (Bit True)
+    M.write arr 2 (Bit True)
+    M.basicSet (M.slice 1 1 arr) (Bit False)
     (,) <$> M.read arr 0 <*> M.read arr 2
 
 case_set_read1 :: IO ()
-case_set_read1 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_set_read1 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 1
-    M.basicSet arr (fromBool True)
+    M.basicSet arr (Bit True)
     M.read arr 0
 
 case_set_read2 :: IO ()
-case_set_read2 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_set_read2 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 2
-    M.basicSet (M.slice 1 1 arr) (fromBool True)
+    M.basicSet (M.slice 1 1 arr) (Bit True)
     M.read arr 1
 
 case_set_read3 :: IO ()
-case_set_read3 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_set_read3 = assertEqual "should be equal" (Bit True) $ runST $ do
     arr <- M.new 192
-    M.basicSet (M.slice 71 121 arr) (fromBool True)
+    M.basicSet (M.slice 71 121 arr) (Bit True)
     M.read arr 145
 
 case_write_copy_read1 :: IO ()
-case_write_copy_read1 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_copy_read1 = assertEqual "should be equal" (Bit True) $ runST $ do
     src <- M.slice 37 28 <$> M.new 65
-    M.write src 27 (fromBool True)
+    M.write src 27 (Bit True)
     dst <- M.slice 37 28 <$> M.new 65
     M.copy dst src
     M.read dst 27
 
 case_write_copy_read2 :: IO ()
-case_write_copy_read2 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_copy_read2 = assertEqual "should be equal" (Bit True) $ runST $ do
     src <- M.slice 32 33 <$> M.new 65
-    M.write src 0 (fromBool True)
+    M.write src 0 (Bit True)
     dst <- M.slice 32 33 <$> M.new 65
     M.copy dst src
     M.read dst 0
 
 case_write_copy_read3 :: IO ()
-case_write_copy_read3 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_copy_read3 = assertEqual "should be equal" (Bit True) $ runST $ do
     src <- M.slice 1 1 <$> M.new 2
-    M.write src 0 (fromBool True)
+    M.write src 0 (Bit True)
     dst <- M.slice 1 1 <$> M.new 2
     M.copy dst src
     M.read dst 0
 
 case_write_copy_read4 :: IO ()
-case_write_copy_read4 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_copy_read4 = assertEqual "should be equal" (Bit True) $ runST $ do
     src <- M.slice 12 52 <$> M.new 64
-    M.write src 22 (fromBool True)
+    M.write src 22 (Bit True)
     dst <- M.slice 12 52 <$> M.new 64
     M.copy dst src
     M.read dst 22
 
 case_write_copy_read5 :: IO ()
-case_write_copy_read5 = assertEqual "should be equal" (fromBool True) $ runST $ do
+case_write_copy_read5 = assertEqual "should be equal" (Bit True) $ runST $ do
     src <- M.slice 48 80 <$> M.new 128
-    M.write src 46 (fromBool True)
+    M.write src 46 (Bit True)
     dst <- M.slice 48 80 <$> M.new 128
     M.copy dst src
     M.read dst 46
 
-prop_slice_def :: Int -> Int -> N.New U.Vector Bit -> Bool
+prop_slice_def :: Int -> Int -> N.New B.Vector Bit -> Bool
 prop_slice_def s n xs = runST $ do
     let xs' = V.new xs
         (s', n') = trimSlice s n (V.length xs')
@@ -207,23 +208,23 @@
     (\xs -> do U.writeWord            xs  (n `mod` M.length xs) w
                V.unsafeFreeze xs)
 
-prop_wordLength_def :: N.New U.Vector Bit -> Bool
+prop_wordLength_def :: N.New B.Vector Bit -> Bool
 prop_wordLength_def xs
     =  runST (fmap U.wordLength (N.run xs))
-    == runST (fmap U.length (N.run xs >>= U.cloneToWords))
+    == runST (fmap M.length (N.run xs >>= U.cloneToWords))
 
-prop_cloneFromWords_def :: Int -> Int -> N.New U.Vector Word -> Bool
+prop_cloneFromWords_def :: Int -> Int -> N.New B.Vector Word -> Bool
 prop_cloneFromWords_def maxN n' ws
     =  runST (N.run ws >>= U.cloneFromWords n >>= V.unsafeFreeze)
     == B.fromWords n (V.new ws)
     where n = n' `mod` maxN
 
-prop_cloneToWords_def :: N.New U.Vector Bit -> Bool
+prop_cloneToWords_def :: N.New B.Vector Bit -> Bool
 prop_cloneToWords_def xs
     =  runST (N.run xs >>= U.cloneToWords >>= V.unsafeFreeze)
     == B.toWords (V.new xs)
 
-prop_mapMInPlaceWithIndex_leftToRight :: N.New U.Vector Bit -> Bool
+prop_mapMInPlaceWithIndex_leftToRight :: N.New B.Vector Bit -> Bool
 prop_mapMInPlaceWithIndex_leftToRight xs
     = runST $ do
         x <- newSTRef (-1)
@@ -234,9 +235,9 @@
                 return (if i > j then maxBound else 0)
         U.mapMInPlaceWithIndex f xs1
         xs2 <- V.unsafeFreeze xs1
-        return (all toBool (B.toList xs2))
+        return (all unBit (B.toList xs2))
 
-prop_mapMInPlaceWithIndex_aligned :: N.New U.Vector Bit -> Bool
+prop_mapMInPlaceWithIndex_aligned :: N.New B.Vector Bit -> Bool
 prop_mapMInPlaceWithIndex_aligned xs = runST $ do
     ok <- newSTRef True
     xs1 <- N.run xs
@@ -247,17 +248,17 @@
     U.mapMInPlaceWithIndex f xs1
     readSTRef ok
 
-prop_countBits_def :: N.New U.Vector Bit -> Bool
+prop_countBits_def :: N.New B.Vector Bit -> Bool
 prop_countBits_def xs
     =  runST (N.run xs >>= U.countBits)
     == B.countBits (V.new xs)
 
-prop_listBits_def :: N.New U.Vector Bit -> Bool
+prop_listBits_def :: N.New B.Vector Bit -> Bool
 prop_listBits_def xs
     =  runST (N.run xs >>= U.listBits)
     == B.listBits (V.new xs)
 
-prop_reverseInPlace_def :: N.New U.Vector Bit -> Bool
+prop_reverseInPlace_def :: N.New B.Vector Bit -> Bool
 prop_reverseInPlace_def xs
     =  runST (N.run xs >>= \v -> U.reverseInPlace v >> V.unsafeFreeze v)
     == B.reverse (V.new xs)
diff --git a/test/Tests/SetOps.hs b/test/Tests/SetOps.hs
--- a/test/Tests/SetOps.hs
+++ b/test/Tests/SetOps.hs
@@ -4,6 +4,7 @@
 
 import Data.Bit
 import Data.Bits
+import qualified Data.Vector.Unboxed as U
 import qualified Data.Vector.Unboxed.Bit as U
 import Test.Framework (Test, testGroup)
 import Test.Framework.Providers.QuickCheck2 (testProperty)
@@ -54,13 +55,13 @@
 prop_unions_def :: Int -> Int -> [U.Vector Bit] -> Bool
 prop_unions_def maxN n' xss
     =  U.unions n xss
-    == U.take n (foldr U.union (U.replicate n 0) (map (U.pad n) xss))
+    == U.take n (foldr U.union (U.replicate n (Bit False)) (map (U.pad n) xss))
     where n = n' `mod` maxN
 
 prop_intersections_def :: Int -> Int -> [U.Vector Bit] -> Bool
 prop_intersections_def maxN n' xss
     =  U.intersections n xss
-    == U.take n (foldr U.intersection (U.replicate n 1) (map (U.padWith 1 n) xss))
+    == U.take n (foldr U.intersection (U.replicate n (Bit True)) (map (U.padWith (Bit True) n) xss))
     where n = n' `mod` maxN
 
 prop_invert_def :: U.Vector Bit -> Bool
@@ -71,12 +72,12 @@
 prop_select_def :: U.Vector Bit -> U.Vector Word -> Bool
 prop_select_def xs ys
     =  U.select xs ys
-    == [ x | (1, x) <- zip (U.toList xs) (U.toList ys)]
+    == [ x | (Bit True, x) <- zip (U.toList xs) (U.toList ys)]
 
 prop_exclude_def :: U.Vector Bit -> U.Vector Word -> Bool
 prop_exclude_def xs ys
     =  U.exclude xs ys
-    == [ x | (0, x) <- zip (U.toList xs) (U.toList ys)]
+    == [ x | (Bit False, x) <- zip (U.toList xs) (U.toList ys)]
 
 prop_selectBits_def :: U.Vector Bit -> U.Vector Bit -> Bool
 prop_selectBits_def xs ys
diff --git a/test/Tests/Vector.hs b/test/Tests/Vector.hs
--- a/test/Tests/Vector.hs
+++ b/test/Tests/Vector.hs
@@ -5,6 +5,7 @@
 import Data.Bit
 import Data.Bits
 import Data.List
+import qualified Data.Vector.Unboxed as U hiding (reverse, and, or, any, all, findIndex)
 import qualified Data.Vector.Unboxed.Bit as U
 import Test.Framework (Test, testGroup)
 import Test.Framework.Providers.HUnit (testCase)
@@ -66,7 +67,7 @@
 prop_fromWords_def :: Int -> Int -> U.Vector Word -> Bool
 prop_fromWords_def maxN n ws
     =  U.toList (U.fromWords n' ws)
-    == take n' (concatMap wordToBitList (U.toList ws) ++ repeat 0)
+    == take n' (concatMap wordToBitList (U.toList ws) ++ repeat (Bit False))
     where n' = n `mod` maxN
 
 prop_toWords_def :: U.Vector Bit -> Bool
@@ -100,22 +101,22 @@
 prop_countBits_def :: U.Vector Bit -> Bool
 prop_countBits_def xs
     =  U.countBits xs
-    == length (filter toBool (U.toList xs))
+    == length (filter unBit (U.toList xs))
 
 prop_listBits_def :: U.Vector Bit -> Bool
 prop_listBits_def xs
     =  U.listBits xs
-    == [ i | (i,x) <- zip [0..] (U.toList xs), toBool x]
+    == [ i | (i,x) <- zip [0..] (U.toList xs), unBit x]
 
 prop_and_def :: U.Vector Bit -> Bool
 prop_and_def xs
     =  U.and xs
-    == all toBool (U.toList xs)
+    == all unBit (U.toList xs)
 
 prop_or_def :: U.Vector Bit -> Bool
 prop_or_def xs
     =  U.or xs
-    == any toBool (U.toList xs)
+    == any unBit (U.toList xs)
 
 prop_any_def :: Fun Bit Bool -> U.Vector Bit -> Bool
 prop_any_def f' xs
