diff --git a/bv-sized.cabal b/bv-sized.cabal
--- a/bv-sized.cabal
+++ b/bv-sized.cabal
@@ -1,5 +1,5 @@
 name:                bv-sized
-version:             0.2.1
+version:             0.3.0
 category:            Bit Vectors
 synopsis:            a BitVector datatype that is parameterized by the vector width
 description:
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -22,3 +22,10 @@
   * bvDivU, bvDivS
   * Added Read instance, fixed Show to be compatible. Using prettyclass for
     pretty printing. (I guess this is semi-breaking, but whatever.)
+
+## 0.3.0 *April 2018*
+  * fixed bug with bvShiftR, it was doing a left shift!
+  * Division now rounds to zero for negative integers, bvDiv -> bvQuot
+  * added Ix instance for BitVector w
+  * added bv0, zero-width vector
+  * bvConcatMany, bvGetBytesU (conversion to/from list of bytes)
diff --git a/src/Data/BitVector/Sized.hs b/src/Data/BitVector/Sized.hs
--- a/src/Data/BitVector/Sized.hs
+++ b/src/Data/BitVector/Sized.hs
@@ -22,6 +22,7 @@
   ( -- * BitVector type
     BitVector(..)
   , bitVector
+  , bv0
     -- * Bitwise operations (width-preserving)
     -- | These are alternative versions of some of the 'Bits' functions where we do
     -- not need to know the width at compile time. They are all width-preserving.
@@ -33,13 +34,15 @@
   , bvPopCount
   , bvTruncBits
     -- * Arithmetic operations (width-preserving)
-  , bvAdd, bvMul, bvDivU, bvDivS
+  , bvAdd, bvMul
+  , bvQuotU, bvQuotS
+  , bvRemU, bvRemS
   , bvAbs, bvNegate
   , bvSignum
   , bvLTS, bvLTU
     -- * Variable-width operations
     -- | These are functions that involve bit vectors of different lengths.
-  , bvConcat, (<:>)
+  , bvConcat, (<:>), bvConcatMany, bvConcatManyWithRepr
   , bvExtract, bvExtractWithRepr
   , bvZext, bvZextWithRepr
   , bvSext, bvSextWithRepr
@@ -47,11 +50,13 @@
     -- * Conversions to Integer
   , bvIntegerU
   , bvIntegerS
+    -- * Byte decomposition
+  , bvGetBytesU
   ) where
 
 import Data.Bits
-import Data.Parameterized.Classes
-import Data.Parameterized.NatRepr
+import Data.Ix
+import Data.Parameterized
 import GHC.TypeLits
 import Numeric
 import System.Random
@@ -69,18 +74,22 @@
 
 -- | Construct a bit vector with a particular width, where the width is inferrable
 -- from the type context. The 'Integer' input (an unbounded data type, hence with an
--- infinite-width bit representation), whether positive or negative is silently
+-- infinite-width bit representation), whether positive or negative, is silently
 -- truncated to fit into the number of bits demanded by the return type.
 --
 -- >>> bitVector 0xA :: BitVector 4
 -- 0xa
--- >>> :type it
--- it :: BitVector 4
+-- >>> bitVector 0xA :: BitVector 2
+-- 0x2
 bitVector :: KnownNat w => Integer -> BitVector w
 bitVector x = BV wRepr (truncBits width (fromIntegral x))
   where wRepr = knownNat
         width = natValue wRepr
 
+-- | The zero bitvector with width 0.
+bv0 :: BitVector 0
+bv0 = bitVector 0
+
 ----------------------------------------
 -- BitVector -> Integer functions
 
@@ -115,7 +124,7 @@
 bvComplement (BV wRepr x) = BV wRepr (truncBits width (complement x))
   where width = natValue wRepr
 
--- | Bitwise shift.
+-- | Bitwise shift. Uses an arithmetic right shift.
 bvShift :: BitVector w -> Int -> BitVector w
 bvShift bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` shf))
   where width = natValue wRepr
@@ -135,7 +144,7 @@
 
 -- | Right logical shift.
 bvShiftRL :: BitVector w -> Int -> BitVector w
-bvShiftRL bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` toPos shf))
+bvShiftRL bv@(BV wRepr _) shf = BV wRepr (truncBits width (x `shift` (- toPos shf)))
   where width = natValue wRepr
         x     = bvIntegerU bv
 
@@ -176,17 +185,29 @@
 bvMul (BV wRepr x) (BV _ y) = BV wRepr (truncBits width (x * y))
   where width = natValue wRepr
 
--- | Bitwise division (unsigned).
-bvDivU :: BitVector w -> BitVector w -> BitVector w
-bvDivU (BV wRepr x) (BV _ y) = BV wRepr (x `div` y)
+-- | Bitwise division (unsigned). Rounds to zero.
+bvQuotU :: BitVector w -> BitVector w -> BitVector w
+bvQuotU (BV wRepr x) (BV _ y) = BV wRepr (x `quot` y)
 
--- | Bitwise division (signed).
-bvDivS :: BitVector w -> BitVector w -> BitVector w
-bvDivS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `div` y))
+-- | Bitwise division (signed). Rounds to zero (not negative infinity).
+bvQuotS :: BitVector w -> BitVector w -> BitVector w
+bvQuotS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `quot` y))
   where x = bvIntegerS bv1
         y = bvIntegerS bv2
         width = natValue wRepr
 
+-- | Bitwise remainder after division (unsigned), when rounded to zero.
+bvRemU :: BitVector w -> BitVector w -> BitVector w
+bvRemU (BV wRepr x) (BV _ y) = BV wRepr (x `rem` y)
+
+-- | Bitwise remainder after  division (signed), when rounded to zero (not negative
+-- infinity).
+bvRemS :: BitVector w -> BitVector w -> BitVector w
+bvRemS bv1@(BV wRepr _) bv2 = BV wRepr (truncBits width (x `rem` y))
+  where x = bvIntegerS bv1
+        y = bvIntegerS bv2
+        width = natValue wRepr
+
 -- | Bitwise absolute value.
 bvAbs :: BitVector w -> BitVector w
 bvAbs bv@(BV wRepr _) = BV wRepr abs_x
@@ -233,6 +254,26 @@
 (<:>) :: BitVector v -> BitVector w -> BitVector (v+w)
 (<:>) = bvConcat
 
+bvConcatSome :: Some BitVector -> Some BitVector -> Some BitVector
+bvConcatSome (Some bv1) (Some bv2) = Some (bv2 <:> bv1)
+
+-- | Concatenate a list of 'BitVector's into a 'BitVector' of arbitrary width. The ordering is little endian:
+--
+-- >>> bvConcatMany [0xAA :: BitVector 8, 0xBB] :: BitVector 16
+-- 0xbbaa
+-- >>> bvConcatMany [0xAA :: BitVector 8, 0xBB, 0xCC] :: BitVector 16
+-- 0xbbaa
+--
+-- If the sum of the widths of the input 'BitVector's exceeds the output width, we
+-- ignore the tail end of the list.
+bvConcatMany :: KnownNat w' => [BitVector w] -> BitVector w'
+bvConcatMany = bvConcatManyWithRepr knownNat
+
+-- | 'bvConcatMany' with an explicit 'NatRepr'.
+bvConcatManyWithRepr :: NatRepr w' -> [BitVector w] -> BitVector w'
+bvConcatManyWithRepr wRepr bvs =
+  viewSome (bvZextWithRepr wRepr) $ foldl bvConcatSome (Some bv0) (Some <$> bvs)
+
 infixl 6 <:>
 
 -- | Slice out a smaller bit vector from a larger one. The lowest significant bit is
@@ -313,6 +354,17 @@
         width = natValue prodRepr
 
 ----------------------------------------
+-- Byte decomposition
+
+-- | Given a 'BitVector' of arbitrary length, decompose it into a list of bytes. Uses
+-- an unsigned interpretation of the input vector, so if you ask for more bytes that
+-- the 'BitVector' contains, you get zeros. The result is little-endian, so the first
+-- element of the list will be the least significant byte of the input vector.
+bvGetBytesU :: Int -> BitVector w -> [BitVector 8]
+bvGetBytesU n _ | n <= 0 = []
+bvGetBytesU n bv = bvExtract 0 bv : bvGetBytesU (n-1) (bvShiftRL bv 8)
+
+----------------------------------------
 -- Class instances
 
 instance Show (BitVector w) where
@@ -368,6 +420,11 @@
   toEnum   = bitVector . fromIntegral
   fromEnum = fromIntegral . bvIntegerU
 
+instance KnownNat w => Ix (BitVector w) where
+  range (lo, hi) = bitVector <$> [bvIntegerU lo .. bvIntegerU hi]
+  index (lo, hi) bv = index (bvIntegerU lo, bvIntegerU hi) (bvIntegerU bv)
+  inRange (lo, hi) bv = inRange (bvIntegerU lo, bvIntegerU hi) (bvIntegerU bv)
+
 instance KnownNat w => Bounded (BitVector w) where
   minBound = bitVector 0
   maxBound = bitVector (-1)
@@ -385,7 +442,7 @@
 
 prettyHex :: (Integral a, PrintfArg a, Show a) => a -> Integer -> String
 prettyHex width val = printf format val width
-  where numDigits = (width+3) `div` 4
+  where numDigits = (width+3) `quot` 4
         format = "0x%." ++ show numDigits ++ "x<%d>"
 
 instance Pretty (BitVector w) where
diff --git a/src/Data/BitVector/Sized/BitLayout.hs b/src/Data/BitVector/Sized/BitLayout.hs
--- a/src/Data/BitVector/Sized/BitLayout.hs
+++ b/src/Data/BitVector/Sized/BitLayout.hs
@@ -36,7 +36,7 @@
 
 import Data.BitVector.Sized
 import Data.Foldable
-import Control.Lens
+import Control.Lens (lens, Simple, Lens)
 import Data.Parameterized
 import qualified Data.Sequence as S
 import Data.Sequence (Seq)
