+-- | Unsafe indexing.
+--
+-- Examples:
+--
+-- >>> let v1 = make3d (1,2,3)
+-- >>> v1 ! 2
+-- 3
+-- >>> v1 ! 3
+-- *** Exception: Data.Vector.Fixed.!: index out of range
+--
+(!) :: (V.Vector v a) => Vn (v a) -> Int -> a
+(!) (Vn v1) idx = v1 V.! idx
+
+
+-- | Safe indexing.
+-- Examples:
+--
+-- >>> let v1 = make3d (1,2,3)
+-- >>> v1 !? 2
+-- Just 3
+-- >>> v1 !? 3
+-- Nothing
+--
+(!?) :: (V.Vector v a) => Vn (v a) -> Int -> Maybe a
+(!?) v1@(Vn v2) idx
+ | idx < 0 || idx >= V.length v2 = Nothing
+ | otherwise = Just $ v1 ! idx
+
+
+-- * Two- and three-dimensional wrappers.
+--
+-- These two wrappers are instances of 'Vector', so they inherit all
+-- of the userful instances defined above. But, they use fixed
+-- constructors, so you can pattern match out the individual
+-- components.
+
+data Vec2D a = Vec2D a a
+type instance V.Dim Vec2D = V.N2
+instance V.Vector Vec2D a where
+ inspect (Vec2D x y) (V.Fun f) = f x y
+ construct = V.Fun Vec2D
+
+data Vec3D a = Vec3D a a a
+type instance V.Dim Vec3D = V.N3
+instance V.Vector Vec3D a where
+ inspect (Vec3D x y z) (V.Fun f) = f x y z
+ construct = V.Fun Vec3D
+