-- Copyright 2020 Google LLC
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Array.Convert(Convert(..)) where
import Data.Proxy
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Storable as VS
import GHC.TypeLits(KnownNat)

import qualified Data.Array.Internal as I
import qualified Data.Array.Internal.Dynamic as D
import qualified Data.Array.Internal.DynamicG as DG
import qualified Data.Array.Internal.DynamicS as DS
import qualified Data.Array.Internal.DynamicU as DU
import qualified Data.Array.Internal.Ranked as R
import qualified Data.Array.Internal.RankedG as RG
import qualified Data.Array.Internal.RankedS as RS
import qualified Data.Array.Internal.RankedU as RU
import qualified Data.Array.Internal.Shaped as S
import qualified Data.Array.Internal.ShapedG as SG
import qualified Data.Array.Internal.ShapedS as SS
import qualified Data.Array.Internal.ShapedU as SU
import Data.Array.Internal.Shape(Shape(..))

class Convert a b where
  -- | Convert between two array types.
  -- If both arrays have the same flavor of boxing this is a O(1)
  -- operation. Conversion between different boxing is a O(n) operation.
  convert  :: a -> b
  -- | Convert between two array types if possible, or return error message.
  convertE :: a -> Either String b
  {-# INLINE convert #-}
  convert = ([Char] -> b) -> (b -> b) -> Either [Char] b -> b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> b
forall a. HasCallStack => [Char] -> a
error b -> b
forall a. a -> a
id (Either [Char] b -> b) -> (a -> Either [Char] b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either [Char] b
forall a b. Convert a b => a -> Either [Char] b
convertE
  {-# INLINE convertE #-}
  convertE = b -> Either [Char] b
forall a b. b -> Either a b
Right (b -> Either [Char] b) -> (a -> b) -> a -> Either [Char] b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall a b. Convert a b => a -> b
convert
  {-# MINIMAL convert | convertE #-}

-- We write these instances like "instance (a ~ b) => Convert (X a) (Y b)" so
-- that instance resolution will commit to them as soon as it knows the array
-- types, and then introduce an equality constraint on the element types.  This
-- way, if you call 'convert' on an array, type inference can propagate the
-- element type across the conversion.  If we wrote them like  "instance
-- Convert (X a) (Y a)" instead, they'd not be selected until the element types
-- of both arrays are determined to be the same by other means, which would
-- lead to unnecessary ambiguity errors.

-----

instance (a ~ b, DU.Unbox a) => Convert (D.Array a) (DU.Array b) where
  convert :: Array a -> Array b
convert (D.A (DG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
DU.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, DU.Unbox a) => Convert (DU.Array a) (D.Array b) where
  convert :: Array a -> Array b
convert (DU.A (DG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
D.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

instance (a ~ b, DS.Unbox a) => Convert (D.Array a) (DS.Array b) where
  convert :: Array a -> Array b
convert (D.A (DG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
DS.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, DS.Unbox a) => Convert (DS.Array a) (D.Array b) where
  convert :: Array a -> Array b
convert (DS.A (DG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
D.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

-- As above with the element types, we arrange to select the Convert instance
-- before the ranks are known to be equal, then constrain them to be equal.

instance (a ~ b, n ~ m, RU.Unbox a) => Convert (R.Array n a) (RU.Array m b) where
  convert :: Array n a -> Array m b
convert (R.A (RG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (n :: Nat) a. Array n Vector a -> Array n a
RU.A (ShapeL -> T Vector a -> Array m Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, n ~ m, RU.Unbox a) => Convert (RU.Array n a) (R.Array m b) where
  convert :: Array n a -> Array m b
convert (RU.A (RG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (n :: Nat) a. Array n Vector a -> Array n a
R.A (ShapeL -> T Vector a -> Array m Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

instance (a ~ b, n ~ m, RS.Unbox a) => Convert (R.Array n a) (RS.Array m b) where
  convert :: Array n a -> Array m b
convert (R.A (RG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (n :: Nat) a. Array n Vector a -> Array n a
RS.A (ShapeL -> T Vector a -> Array m Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, n ~ m, RS.Unbox a) => Convert (RS.Array n a) (R.Array m b) where
  convert :: Array n a -> Array m b
convert (RS.A (RG.A ShapeL
sh (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (n :: Nat) a. Array n Vector a -> Array n a
R.A (ShapeL -> T Vector a -> Array m Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

instance (a ~ b, n ~ m, SU.Unbox a) => Convert (S.Array n a) (SU.Array m b) where
  convert :: Array n a -> Array m b
convert (S.A (SG.A (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
SU.A (T Vector a -> Array m Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, n ~ m, SU.Unbox a) => Convert (SU.Array n a) (S.Array m b) where
  convert :: Array n a -> Array m b
convert (SU.A (SG.A (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
S.A (T Vector a -> Array m Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

instance (a ~ b, n ~ m, SS.Unbox a) => Convert (S.Array n a) (SS.Array m b) where
  convert :: Array n a -> Array m b
convert (S.A (SG.A (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
SS.A (T Vector a -> Array m Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

instance (a ~ b, n ~ m, SS.Unbox a) => Convert (SS.Array n a) (S.Array m b) where
  convert :: Array n a -> Array m b
convert (SS.A (SG.A (I.T ShapeL
s N
o Vector a
v))) = Array m Vector a -> Array m a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
S.A (T Vector a -> Array m Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A (ShapeL -> N -> Vector a -> T Vector a
forall (v :: * -> *) a. ShapeL -> N -> v a -> T v a
I.T ShapeL
s N
o (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert Vector a
v)))

-----

instance (a ~ b) => Convert (R.Array n a) (D.Array b) where
  convert :: Array n a -> Array b
convert (R.A (RG.A ShapeL
sh T Vector a
t)) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
D.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A ShapeL
sh T Vector a
t)

instance (a ~ b, KnownNat n) => Convert (D.Array a) (R.Array n b) where
  convertE :: Array a -> Either [Char] (Array n b)
convertE (D.A (DG.A ShapeL
sh T Vector a
t)) | ShapeL -> N
forall (t :: * -> *) a. Foldable t => t a -> N
length ShapeL
sh N -> N -> Bool
forall a. Eq a => a -> a -> Bool
/= forall i. (KnownNat n, Num i) => i
forall (n :: Nat) i. (KnownNat n, Num i) => i
I.valueOf @n = [Char] -> Either [Char] (Array n b)
forall a b. a -> Either a b
Left [Char]
"rank mismatch"
                             | Bool
otherwise = Array n a -> Either [Char] (Array n a)
forall a b. b -> Either a b
Right (Array n a -> Either [Char] (Array n a))
-> Array n a -> Either [Char] (Array n a)
forall a b. (a -> b) -> a -> b
$ Array n Vector a -> Array n a
forall (n :: Nat) a. Array n Vector a -> Array n a
R.A (ShapeL -> T Vector a -> Array n Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh T Vector a
t)

instance (a ~ b, S.Shape sh) => Convert (S.Array sh a) (D.Array b) where
  convert :: Array sh a -> Array b
convert (S.A a :: Array sh Vector a
a@(SG.A T Vector a
t)) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
D.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A (Array sh Vector a -> ShapeL
forall (sh :: [Nat]) (v :: * -> *) a.
Shape sh =>
Array sh v a -> ShapeL
SG.shapeL Array sh Vector a
a) T Vector a
t)

instance (a ~ b, S.Rank sh ~ n, S.Shape sh) => Convert (S.Array sh a) (R.Array n b) where
  convert :: Array sh a -> Array n b
convert (S.A a :: Array sh Vector a
a@(SG.A T Vector a
t)) = Array n Vector a -> Array n a
forall (n :: Nat) a. Array n Vector a -> Array n a
R.A (ShapeL -> T Vector a -> Array n Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A (Array sh Vector a -> ShapeL
forall (sh :: [Nat]) (v :: * -> *) a.
Shape sh =>
Array sh v a -> ShapeL
SG.shapeL Array sh Vector a
a) T Vector a
t)

instance (a ~ b, S.Shape sh) => Convert (D.Array a) (S.Array sh b) where
  convertE :: Array a -> Either [Char] (Array sh b)
convertE (D.A (DG.A ShapeL
sh T Vector a
t)) | ShapeL
sh ShapeL -> ShapeL -> Bool
forall a. Eq a => a -> a -> Bool
== Proxy sh -> ShapeL
forall (s :: [Nat]). Shape s => Proxy s -> ShapeL
shapeP (Proxy sh
forall k (t :: k). Proxy t
Proxy :: Proxy sh) = Array sh a -> Either [Char] (Array sh a)
forall a b. b -> Either a b
Right (Array sh a -> Either [Char] (Array sh a))
-> Array sh a -> Either [Char] (Array sh a)
forall a b. (a -> b) -> a -> b
$ Array sh Vector a -> Array sh a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
S.A (T Vector a -> Array sh Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A T Vector a
t)
  convertE Array a
_ = [Char] -> Either [Char] (Array sh b)
forall a b. a -> Either a b
Left [Char]
"shape mismatch"

instance (a ~ b, S.Rank sh ~ n, S.Shape sh) => Convert (R.Array n a) (S.Array sh b) where
  convertE :: Array n a -> Either [Char] (Array sh b)
convertE (R.A (RG.A ShapeL
sh T Vector a
t)) | ShapeL
sh ShapeL -> ShapeL -> Bool
forall a. Eq a => a -> a -> Bool
== Proxy sh -> ShapeL
forall (s :: [Nat]). Shape s => Proxy s -> ShapeL
shapeP (Proxy sh
forall k (t :: k). Proxy t
Proxy :: Proxy sh) = Array sh a -> Either [Char] (Array sh a)
forall a b. b -> Either a b
Right (Array sh a -> Either [Char] (Array sh a))
-> Array sh a -> Either [Char] (Array sh a)
forall a b. (a -> b) -> a -> b
$ Array sh Vector a -> Array sh a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
S.A (T Vector a -> Array sh Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A T Vector a
t)
  convertE Array n a
_ = [Char] -> Either [Char] (Array sh b)
forall a b. a -> Either a b
Left [Char]
"shape mismatch"

------

instance (a ~ b, KnownNat n) => Convert (DS.Array a) (RS.Array n b) where
  convertE :: Array a -> Either [Char] (Array n b)
convertE (DS.A (DG.A ShapeL
sh T Vector a
t)) | ShapeL -> N
forall (t :: * -> *) a. Foldable t => t a -> N
length ShapeL
sh N -> N -> Bool
forall a. Eq a => a -> a -> Bool
/= forall i. (KnownNat n, Num i) => i
forall (n :: Nat) i. (KnownNat n, Num i) => i
I.valueOf @n = [Char] -> Either [Char] (Array n b)
forall a b. a -> Either a b
Left [Char]
"rank mismatch"
                              | Bool
otherwise = Array n a -> Either [Char] (Array n a)
forall a b. b -> Either a b
Right (Array n a -> Either [Char] (Array n a))
-> Array n a -> Either [Char] (Array n a)
forall a b. (a -> b) -> a -> b
$ Array n Vector a -> Array n a
forall (n :: Nat) a. Array n Vector a -> Array n a
RS.A (ShapeL -> T Vector a -> Array n Vector a
forall (n :: Nat) (v :: * -> *) a. ShapeL -> T v a -> Array n v a
RG.A ShapeL
sh T Vector a
t)

instance (a ~ b, SS.Rank sh ~ n, SS.Shape sh) => Convert (RS.Array n a) (SS.Array sh b) where
  convertE :: Array n a -> Either [Char] (Array sh b)
convertE (RS.A (RG.A ShapeL
sh T Vector a
t)) | ShapeL
sh ShapeL -> ShapeL -> Bool
forall a. Eq a => a -> a -> Bool
== Proxy sh -> ShapeL
forall (s :: [Nat]). Shape s => Proxy s -> ShapeL
shapeP (Proxy sh
forall k (t :: k). Proxy t
Proxy :: Proxy sh) = Array sh a -> Either [Char] (Array sh a)
forall a b. b -> Either a b
Right (Array sh a -> Either [Char] (Array sh a))
-> Array sh a -> Either [Char] (Array sh a)
forall a b. (a -> b) -> a -> b
$ Array sh Vector a -> Array sh a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
SS.A (T Vector a -> Array sh Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A T Vector a
t)
  convertE Array n a
_ = [Char] -> Either [Char] (Array sh b)
forall a b. a -> Either a b
Left [Char]
"shape mismatch"

instance (a ~ b, SS.Shape sh) => Convert (DS.Array a) (SS.Array sh b) where
  convertE :: Array a -> Either [Char] (Array sh b)
convertE (DS.A (DG.A ShapeL
sh T Vector a
t)) | ShapeL
sh ShapeL -> ShapeL -> Bool
forall a. Eq a => a -> a -> Bool
== ShapeL
sh' = Array sh a -> Either [Char] (Array sh a)
forall a b. b -> Either a b
Right (Array sh a -> Either [Char] (Array sh a))
-> Array sh a -> Either [Char] (Array sh a)
forall a b. (a -> b) -> a -> b
$ Array sh Vector a -> Array sh a
forall (sh :: [Nat]) a. Array sh Vector a -> Array sh a
SS.A (T Vector a -> Array sh Vector a
forall (sh :: [Nat]) (v :: * -> *) a. T v a -> Array sh v a
SG.A T Vector a
t)
                              | Bool
otherwise = [Char] -> Either [Char] (Array sh b)
forall a b. a -> Either a b
Left ([Char] -> Either [Char] (Array sh b))
-> [Char] -> Either [Char] (Array sh b)
forall a b. (a -> b) -> a -> b
$ [Char]
"shape mismatch: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (ShapeL, ShapeL) -> [Char]
forall a. Show a => a -> [Char]
show (ShapeL
sh, ShapeL
sh')
                              where sh' :: ShapeL
sh' = Proxy sh -> ShapeL
forall (s :: [Nat]). Shape s => Proxy s -> ShapeL
shapeP (Proxy sh
forall k (t :: k). Proxy t
Proxy :: Proxy sh)

instance (a ~ b, SS.Shape sh) => Convert (SS.Array sh a) (DS.Array b) where
  convert :: Array sh a -> Array b
convert (SS.A a :: Array sh Vector a
a@(SG.A T Vector a
t)) = Array Vector a -> Array a
forall a. Array Vector a -> Array a
DS.A (ShapeL -> T Vector a -> Array Vector a
forall (v :: * -> *) a. ShapeL -> T v a -> Array v a
DG.A (Array sh Vector a -> ShapeL
forall (sh :: [Nat]) (v :: * -> *) a.
Shape sh =>
Array sh v a -> ShapeL
SG.shapeL Array sh Vector a
a) T Vector a
t)

------

instance (a ~ b) => Convert (D.Array a) (DG.Array V.Vector b) where
  convert :: Array a -> Array Vector b
convert (D.A Array Vector a
a) = Array Vector a
Array Vector b
a

instance (a ~ b) => Convert (DU.Array a) (DG.Array VU.Vector b) where
  convert :: Array a -> Array Vector b
convert (DU.A Array Vector a
a) = Array Vector a
Array Vector b
a

instance (a ~ b) => Convert (DS.Array a) (DG.Array VS.Vector b) where
  convert :: Array a -> Array Vector b
convert (DS.A Array Vector a
a) = Array Vector a
Array Vector b
a

------

instance (a ~ b, n ~ m) => Convert (R.Array n a) (RG.Array m V.Vector b) where
  convert :: Array n a -> Array m Vector b
convert (R.A Array n Vector a
a) = Array n Vector a
Array m Vector b
a

instance (a ~ b, n ~ m) => Convert (RU.Array n a) (RG.Array m VU.Vector b) where
  convert :: Array n a -> Array m Vector b
convert (RU.A Array n Vector a
a) = Array n Vector a
Array m Vector b
a

instance (a ~ b, n ~ m) => Convert (RS.Array n a) (RG.Array m VS.Vector b) where
  convert :: Array n a -> Array m Vector b
convert (RS.A Array n Vector a
a) = Array n Vector a
Array m Vector b
a

------

instance (a ~ b, s ~ t) => Convert (S.Array s a) (SG.Array t V.Vector b) where
  convert :: Array s a -> Array t Vector b
convert (S.A Array s Vector a
a) = Array s Vector a
Array t Vector b
a

instance (a ~ b, s ~ t) => Convert (SU.Array s a) (SG.Array t VU.Vector b) where
  convert :: Array s a -> Array t Vector b
convert (SU.A Array s Vector a
a) = Array s Vector a
Array t Vector b
a

instance (a ~ b, s ~ t) => Convert (SS.Array s a) (SG.Array t VS.Vector b) where
  convert :: Array s a -> Array t Vector b
convert (SS.A Array s Vector a
a) = Array s Vector a
Array t Vector b
a

------

-- XXX need more conversions.