diff --git a/Data/Array/Repa/Index.hs b/Data/Array/Repa/Index.hs
--- a/Data/Array/Repa/Index.hs
+++ b/Data/Array/Repa/Index.hs
@@ -8,12 +8,8 @@
 	, (:.)	(..)
 
 	-- * Common dimensions.
-	, DIM0
-	, DIM1
-	, DIM2
-	, DIM3
-	, DIM4
-	, DIM5)
+	, DIM0, DIM1, DIM2, DIM3, DIM4, DIM5
+        ,       ix1,  ix2,  ix3,  ix4,  ix5)
 where
 import Data.Array.Repa.Shape
 import GHC.Base 		(quotInt, remInt)
@@ -22,13 +18,13 @@
 
 -- | An index of dimension zero
 data Z	= Z
-	deriving (Show, Eq, Ord)
+	deriving (Show, Read, Eq, Ord)
 
 -- | Our index type, used for both shapes and indices.
 infixl 3 :.
 data tail :. head
-	= tail :. head
-	deriving (Show, Eq, Ord)
+	= !tail :. !head
+	deriving (Show, Read, Eq, Ord)
 
 -- Common dimensions
 type DIM0	= Z
@@ -39,41 +35,70 @@
 type DIM5	= DIM4 :. Int
 
 
--- Shape ------------------------------------------------------------------------------------------
+-- | Helper for index construction.
+--
+--   Use this instead of explicit constructors like @(Z :. (x :: Int))@.
+--   The this is sometimes needed to ensure that 'x' is constrained to 
+--   be in @Int@.
+ix1 :: Int -> DIM1
+ix1 x = Z :. x
+{-# INLINE ix1 #-}
+
+ix2 :: Int -> Int -> DIM2
+ix2 y x = Z :. y :. x
+{-# INLINE ix2 #-}
+
+ix3 :: Int -> Int -> Int -> DIM3
+ix3 z y x = Z :. z :. y :. x
+{-# INLINE ix3 #-}
+
+ix4 :: Int -> Int -> Int -> Int -> DIM4
+ix4 a z y x = Z :. a :. z :. y :. x
+{-# INLINE ix4 #-}
+
+ix5 :: Int -> Int -> Int -> Int -> Int -> DIM5
+ix5 b a z y x = Z :. b :. a :. z :. y :. x
+{-# INLINE ix5 #-}
+
+
+-- Shape ----------------------------------------------------------------------
 instance Shape Z where
-	{-# INLINE rank #-}
+	{-# INLINE [1] rank #-}
 	rank _			= 0
 
-	{-# INLINE zeroDim #-}
-	zeroDim			= Z
+	{-# INLINE [1] zeroDim #-}
+	zeroDim		 	= Z
 
-	{-# INLINE unitDim #-}
+	{-# INLINE [1] unitDim #-}
 	unitDim			= Z
 
-	{-# INLINE intersectDim #-}
+	{-# INLINE [1] intersectDim #-}
 	intersectDim _ _	= Z
 
-	{-# INLINE addDim #-}
+	{-# INLINE [1] addDim #-}
 	addDim _ _		= Z
 
-	{-# INLINE size #-}
+	{-# INLINE [1] size #-}
 	size _			= 1
 
-	{-# INLINE sizeIsValid #-}
+	{-# INLINE [1] sizeIsValid #-}
 	sizeIsValid _		= True
 
 
-	{-# INLINE toIndex #-}
+	{-# INLINE [1] toIndex #-}
 	toIndex _ _		= 0
 
-	{-# INLINE fromIndex #-}
+	{-# INLINE [1] fromIndex #-}
 	fromIndex _ _		= Z
 
 
-	{-# INLINE inShapeRange #-}
+	{-# INLINE [1] inShapeRange #-}
 	inShapeRange Z Z Z	= True
 
+        {-# NOINLINE listOfShape #-}
 	listOfShape _		= []
+
+        {-# NOINLINE shapeOfList #-}
 	shapeOfList []		= Z
 	shapeOfList _		= error $ stage ++ ".fromList: non-empty list when converting to Z."
 
@@ -82,29 +107,29 @@
 
 
 instance Shape sh => Shape (sh :. Int) where
-	{-# INLINE rank #-}
+	{-# INLINE [1] rank #-}
 	rank   (sh  :. _)
 		= rank sh + 1
 
-	{-# INLINE zeroDim #-}
+	{-# INLINE [1] zeroDim #-}
 	zeroDim = zeroDim :. 0
 
-	{-# INLINE unitDim #-}
+	{-# INLINE [1] unitDim #-}
 	unitDim = unitDim :. 1
 
-	{-# INLINE intersectDim #-}
+	{-# INLINE [1] intersectDim #-}
 	intersectDim (sh1 :. n1) (sh2 :. n2)
 		= (intersectDim sh1 sh2 :. (min n1 n2))
 
-	{-# INLINE addDim #-}
+	{-# INLINE [1] addDim #-}
 	addDim (sh1 :. n1) (sh2 :. n2)
 		= addDim sh1 sh2 :. (n1 + n2)
 
-	{-# INLINE size #-}
+	{-# INLINE [1] size #-}
 	size  (sh1 :. n)
 		= size sh1 * n
 
-	{-# INLINE sizeIsValid #-}
+	{-# INLINE [1] sizeIsValid #-}
 	sizeIsValid (sh1 :. n)
 		| size sh1 > 0
 		= n <= maxBound `div` size sh1
@@ -112,29 +137,30 @@
 		| otherwise
 		= False
 
-	{-# INLINE toIndex #-}
+	{-# INLINE [1] toIndex #-}
 	toIndex (sh1 :. sh2) (sh1' :. sh2')
 		= toIndex sh1 sh1' * sh2 + sh2'
 
-	{-# INLINE fromIndex #-}
-	fromIndex (ds :. d) n
-	 	= fromIndex ds (n `quotInt` d) :. r
-		where
-		-- If we assume that the index is in range, there is no point
-		-- in computing the remainder for the highest dimension since
-		-- n < d must hold. This saves one remInt per element access which
-		-- is quite a big deal.
-		r 	| rank ds == 0	= n
-			| otherwise	= n `remInt` d
+	{-# INLINE [1] fromIndex #-}
+        fromIndex (ds :. d) n
+                = fromIndex ds (n `quotInt` d) :. r
+                where
+                -- If we assume that the index is in range, there is no point
+                -- in computing the remainder for the highest dimension since
+                -- n < d must hold. This saves one remInt per element access which
+                -- is quite a big deal.
+                r       | rank ds == 0  = n
+                        | otherwise     = n `remInt` d
 
-	{-# INLINE inShapeRange #-}
+	{-# INLINE [1] inShapeRange #-}
 	inShapeRange (zs :. z) (sh1 :. n1) (sh2 :. n2)
 		= (n2 >= z) && (n2 < n1) && (inShapeRange zs sh1 sh2)
 
-
+        {-# NOINLINE listOfShape #-}
        	listOfShape (sh :. n)
 	 = n : listOfShape sh
 
+        {-# NOINLINE shapeOfList #-}
 	shapeOfList xx
 	 = case xx of
 		[]	-> error $ stage ++ ".toList: empty list when converting to  (_ :. Int)"
diff --git a/Data/Array/Repa/Shape.hs b/Data/Array/Repa/Shape.hs
--- a/Data/Array/Repa/Shape.hs
+++ b/Data/Array/Repa/Shape.hs
@@ -7,7 +7,7 @@
         , showShape )
 where
 
--- Shape ------------------------------------------------------------------------------------------
+-- Shape ----------------------------------------------------------------------
 -- | Class of types that can be used as array shapes and indices.
 class Eq sh => Shape sh where
 
diff --git a/Data/PrimitiveArray/Unboxed/Zero.hs b/Data/PrimitiveArray/Unboxed/Zero.hs
--- a/Data/PrimitiveArray/Unboxed/Zero.hs
+++ b/Data/PrimitiveArray/Unboxed/Zero.hs
@@ -21,11 +21,11 @@
 
 -- | Monadic arrays of primitive type.
 
-data MArr0 s sh elm = MArr0 !sh {-# UNPACK #-} !(MutableByteArray s)
+data MArr0 s sh elm = MArr0 !sh !(MutableByteArray s)
 
 -- | Immutable arrays of primitive type.
 
-data Arr0 sh elm = Arr0 !sh {-# UNPACK #-} !ByteArray
+data Arr0 sh elm = Arr0 !sh !ByteArray
 
 
 
diff --git a/Data/PrimitiveArray/Zero.hs b/Data/PrimitiveArray/Zero.hs
--- a/Data/PrimitiveArray/Zero.hs
+++ b/Data/PrimitiveArray/Zero.hs
@@ -22,11 +22,11 @@
 
 -- | Monadic arrays of primitive type.
 
-data MArr0 s sh elm = MArr0 !sh {-# UNPACK #-} !(MutableArray s elm)
+data MArr0 s sh elm = MArr0 !sh !(MutableArray s elm)
 
 -- | Immutable arrays of primitive type.
 
-data Arr0 sh elm = Arr0 !sh {-# UNPACK #-} !(Array elm)
+data Arr0 sh elm = Arr0 !sh !(Array elm)
 
 
 
diff --git a/PrimitiveArray.cabal b/PrimitiveArray.cabal
--- a/PrimitiveArray.cabal
+++ b/PrimitiveArray.cabal
@@ -1,5 +1,5 @@
 Name:           PrimitiveArray
-Version:        0.2.2.0
+Version:        0.3.0.0
 License:        BSD3
 License-file:   LICENSE
 Author:         Christian Hoener zu Siederdissen
@@ -27,9 +27,10 @@
                 We have forked two repa modules: Shape and Index.
                 .
                 Unboxed vectors are available with implementations based on
-                "primitive" and "vector". For some reason, we loose 50%
-                performance with RNAfold if we use "vector" as the underlying
-                data type, while Nussinov78 does not suffer.
+                "primitive" and "vector". The "primitive" version is probably
+                obsolete now, as I don't see any slowdowns anymore. If this
+                continues into GHC 7.6.1, I'll remove the old code (This will
+                probably not break user code using Unboxed.Zero).
 
 Library
   Exposed-modules:
