diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,6 @@
 # Change Log
 
-## 0.4.1
+## 0.4.2
 
 * Allow a wide range of dynamically sorted values (not just expressions)
 * Utility for extracting array accesses
diff --git a/expressions.cabal b/expressions.cabal
--- a/expressions.cabal
+++ b/expressions.cabal
@@ -1,5 +1,5 @@
 name:                expressions
-version:             0.4.1
+version:             0.4.2
 synopsis:            Expressions and Formulae a la carte
 description:
   This package is aimed at providing means of fixing a first-order language and
@@ -54,8 +54,7 @@
                        Data.Expression.Utils.Indexed.Functor,
                        Data.Expression.Utils.Indexed.Show,
                        Data.Expression.Utils.Indexed.Sum,
-                       Data.Expression.Utils.Indexed.Traversable,
-                       Data.Expression.Utils.Indexed.Tuple
+                       Data.Expression.Utils.Indexed.Traversable
   other-extensions:    DataKinds,
                        FlexibleContexts,
                        FlexibleInstances,
diff --git a/src/Data/Expression.hs b/src/Data/Expression.hs
--- a/src/Data/Expression.hs
+++ b/src/Data/Expression.hs
@@ -40,7 +40,6 @@
                        , module Data.Expression.Utils.Indexed.Show
                        , module Data.Expression.Utils.Indexed.Sum
                        , module Data.Expression.Utils.Indexed.Traversable
-                       , module Data.Expression.Utils.Indexed.Tuple
 
                        -- Functors representing usual combinations of languages
                        , QFLogicF
@@ -155,7 +154,6 @@
 import Data.Expression.Utils.Indexed.Show
 import Data.Expression.Utils.Indexed.Sum
 import Data.Expression.Utils.Indexed.Traversable
-import Data.Expression.Utils.Indexed.Tuple
 
 import qualified Data.Functor.Const as F
 import qualified Prelude as P
diff --git a/src/Data/Expression/Array.hs b/src/Data/Expression/Array.hs
--- a/src/Data/Expression/Array.hs
+++ b/src/Data/Expression/Array.hs
@@ -1,6 +1,8 @@
-{-# LANGUAGE FlexibleContexts
+{-# LANGUAGE DerivingVia
+           , FlexibleContexts
            , FlexibleInstances
            , GADTs
+           , LiberalTypeSynonyms
            , MultiParamTypeClasses
            , OverloadedStrings
            , RankNTypes
@@ -21,11 +23,12 @@
                              , select
                              , store
                              , accesses
-                             , StaticallyValuedArrayAccess(..)
-                             , DynamicallyValuedArrayAccess(..)
-                             , StaticallyIndexedArrayAccess(..)
-                             , DynamicallyIndexedArrayAccess(..) ) where
+                             , toStaticallySortedArrayAccess
+                             , ArrayAccess(..)
+                             , DynamicValueArrayAccess(..)
+                             , DynamicArrayAccess ) where
 
+import Control.Monad
 import Control.Monad.Trans.Writer
 import Data.Coerce
 import Data.Functor.Const
@@ -40,7 +43,6 @@
 import Data.Expression.Utils.Indexed.Show
 import Data.Expression.Utils.Indexed.Sum
 import Data.Expression.Utils.Indexed.Traversable
-import Data.Expression.Utils.Indexed.Tuple
 
 -- | A functor representing array-theoretic terms (`select` and `store` also known as "read" and "write")
 data ArrayF a (s :: Sort) where
@@ -115,25 +117,37 @@
 store :: ( ArrayF :<: f, SingI i, SingI e ) => IFix f ('ArraySort i e) -> IFix f i -> IFix f e -> IFix f ('ArraySort i e)
 store a i v = inject (Store sing sing a i v)
 
-newtype StaticallyValuedArrayAccess  f (s :: Sort) (e :: Sort) = StaticallyValuedArrayAccess (IFix f ('ArraySort s e))
-newtype DynamicallyValuedArrayAccess f (s :: Sort)             = DynamicallyValuedArrayAccess (DynamicallySorted (StaticallyValuedArrayAccess f s))
+type Array                   f (e :: Sort) (i :: Sort) = IFix f ('ArraySort i e)
+type Index                   f (i :: Sort)             = IFix f i
 
-newtype StaticallyIndexedArrayAccess  f (s :: Sort) = StaticallyIndexedArrayAccess (IT2 (DynamicallyValuedArrayAccess f) (IFix f) s)
-newtype DynamicallyIndexedArrayAccess f             = DynamicallyIndexedArrayAccess (DynamicallySorted (StaticallyIndexedArrayAccess f))
+newtype ArrayAccess             f (i :: Sort) (e :: Sort) = ArrayAccess             { getAA   :: (Array f e i, Index f i) }            deriving Show via (Array f e i, Index f i)
+newtype DynamicValueArrayAccess f (i :: Sort)             = DynamicValueArrayAccess { getDVAA :: DynamicallySorted (ArrayAccess f i) } deriving Show via (DynamicallySorted (ArrayAccess f i))
+type    DynamicArrayAccess      f                         = DynamicallySorted (DynamicValueArrayAccess f)
 
-instance ( IFunctor f, IShow f ) => Show (StaticallyValuedArrayAccess f i e) where
-  show (StaticallyValuedArrayAccess f) = show f
+-- | Tries to convert access to an array of some sort to an access to an array of a specific sort
+toStaticallySortedArrayAccess :: forall f (i :: Sort) (e :: Sort). ( SingI i, SingI e ) => DynamicArrayAccess f -> Maybe (IFix f ('ArraySort i e), IFix f i)
+toStaticallySortedArrayAccess = elementSort <=< indexSort where
+  elementSort :: DynamicallySorted (ArrayAccess f i) -> Maybe (Array f e i, Index f i)
+  elementSort = fmap getAA . toStaticallySorted
 
-instance ( IFunctor f, IShow f ) => Show (DynamicallyValuedArrayAccess f i) where
-  show (DynamicallyValuedArrayAccess f) = show f
+  indexSort :: DynamicArrayAccess f -> Maybe (DynamicallySorted (ArrayAccess f i))
+  indexSort = fmap getDVAA . toStaticallySorted
 
 -- | Collects pairs of arrays and indices that appear together in some @select@ and/or @store@ within an expression
-accesses :: forall f (s :: Sort). ( ArrayF :<: f, ITraversable f ) => IFix f s -> [DynamicallyIndexedArrayAccess f]
+accesses :: forall f (s :: Sort). ( ArrayF :<: f, ITraversable f ) => IFix f s -> [DynamicArrayAccess f]
 accesses = execWriter . imapM accesses' where
-  accesses' :: forall (s' :: Sort). IFix f s' -> Writer [DynamicallyIndexedArrayAccess f] (IFix f s')
+  accesses' :: forall (s' :: Sort). IFix f s' -> Writer [DynamicArrayAccess f] (IFix f s')
   accesses' e = do
     case match e of
-      Just (Select is es a i)   -> tell [ DynamicallyIndexedArrayAccess (DynamicallySorted is (StaticallyIndexedArrayAccess (IT2 (DynamicallyValuedArrayAccess (DynamicallySorted es (StaticallyValuedArrayAccess a)), i)))) ]
-      Just (Store  is es a i _) -> tell [ DynamicallyIndexedArrayAccess (DynamicallySorted is (StaticallyIndexedArrayAccess (IT2 (DynamicallyValuedArrayAccess (DynamicallySorted es (StaticallyValuedArrayAccess a)), i)))) ]
+      Just (Select is es a i)   -> tell [ DynamicallySorted is
+                                        $ DynamicValueArrayAccess
+                                        $ DynamicallySorted es
+                                        $ ArrayAccess
+                                        $ (a, i) ]
+      Just (Store  is es a i _) -> tell [ DynamicallySorted is
+                                        $ DynamicValueArrayAccess
+                                        $ DynamicallySorted es
+                                        $ ArrayAccess
+                                        $ (a, i) ]
       _                         -> return ()
     return e
diff --git a/src/Data/Expression/Utils/Indexed/Tuple.hs b/src/Data/Expression/Utils/Indexed/Tuple.hs
deleted file mode 100644
--- a/src/Data/Expression/Utils/Indexed/Tuple.hs
+++ /dev/null
@@ -1,64 +0,0 @@
-{-# LANGUAGE TypeInType #-}
-
---------------------------------------------------------------------------------
--- |
--- Module     :  Data.Expression.Array
--- Copyright  :  (C) 2017-18 Jakub Daniel
--- License    :  BSD-style (see the file LICENSE)
--- Maintainer :  Jakub Daniel <jakub.daniel@protonmail.com>
--- Stability  :  experimental
---------------------------------------------------------------------------------
-
-module Data.Expression.Utils.Indexed.Tuple where
-
-newtype IT2 (a :: k -> *)
-            (b :: k -> *)
-            (i :: k) = IT2 { getIT2 :: (a i, b i) }
-
-newtype IT3 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (i :: k) = IT3 { getIT3 :: (a i, b i, c i) }
-
-newtype IT4 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (d :: k -> *)
-            (i :: k) = IT4 { getIT4 :: (a i, b i, c i, d i) }
-
-newtype IT5 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (d :: k -> *)
-            (e :: k -> *)
-            (i :: k) = IT5 { getIT5 :: (a i, b i, c i, d i, e i) }
-
-newtype IT6 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (d :: k -> *)
-            (e :: k -> *)
-            (f :: k -> *)
-            (i :: k) = IT6 { getIT6 :: (a i, b i, c i, d i, e i, f i) }
-
-newtype IT7 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (d :: k -> *)
-            (e :: k -> *)
-            (f :: k -> *)
-            (g :: k -> *)
-            (i :: k) = IT7 { getIT7 :: (a i, b i, c i, d i, e i, f i, g i) }
-
-newtype IT8 (a :: k -> *)
-            (b :: k -> *)
-            (c :: k -> *)
-            (d :: k -> *)
-            (e :: k -> *)
-            (f :: k -> *)
-            (g :: k -> *)
-            (h :: k -> *)
-            (i :: k) = IT8 { getIT8 :: (a i, b i, c i, d i, e i, f i, g i, h i) }
-
-instance ( Show (a i), Show (b i) ) => Show (IT2 a b i) where
-  show (IT2 (a, b)) = "(" ++ show a ++ ", " ++ show b ++ ")"
