I fiddled with a simple tensor library in which I defined the following type.
data Tensor : Vect n Nat -> Type -> Type where
Scalar : a -> Tensor [] a
Dimension : Vect n (Tensor d a) -> Tensor (n :: d) a
A type vector parameter describes tensor "dimensions" or "shape". I am currently trying to define a function for indexing safely Tensor. I planned to do this with help Fin, but I had a problem. Since it Tensorhas an unknown order, I may need any number of indexes, each of which requires a different upper bound. This means that indexes Vectwill not be enough, because each index will have a different type. This made me look at the use of tuples (called "pairs" in Idris?). I wrote the following function to calculate the required type.
TensorIndex : Vect n Nat -> Type
TensorIndex [] = ()
TensorIndex (d::[]) = Fin d
TensorIndex (d::ds) = (Fin d, TensorIndex ds)
This function worked as I expected, calculating the corresponding index type from the dimension vector.
> TensorIndex [4,4,3] -- (Fin 4, Fin 4, Fin 3)
> TensorIndex [2] -- Fin 2
> TensorIndex [] -- ()
index...
index : {d : Vect n Nat} -> TensorIndex d -> Tensor d a -> a
index () (Scalar x) = x
index (a,as) (Dimension xs) = index as $ index a xs
index a (Dimension xs) with (index a xs) | Tensor x = x
... ( , ).
Type mismatch between
(A, B) (Type of (a,as))
and
TensorIndex (n :: d) (Expected type)
, , TensorIndex , , , data; " ". ? TensorIndex , , ? , - index?