Search code examples
coqdependent-typeidris

Dependent types: Vector of vectors


I'm new to dependent types (I'm trying both Idris and Coq, despite their big differences).

I'm trying to express the following type: given a type T and a sequence of k nats n1, n2, ... nk, a type consisting of k sequences of T with length n1, n2, ... nk respectively.

That is, a vector of k vectors, whose lengths are given by a parameter. Is this possible?


Solution

  • You can do this with a heterogeneous list, as follows.

    Require Vector.
    Require Import List.
    Import ListNotations.
    
    Inductive hlist {A : Type} (B : A -> Type) : list A -> Type :=
    | hnil : hlist B []
    | hcons : forall a l, B a -> hlist B l -> hlist B (a :: l).
    
    Definition vector_of_vectors (T : Type) (l : list nat) : Type :=
      hlist (Vector.t T) l.
    

    Then if l is your list of lengths, the type vector_of_vectors T l with will the type you describe.

    For example, we can construct an element of vector_of_vectors bool [2; 0; 1]:

    Section example.
      Definition ls : list nat := [2; 0; 1].
    
      Definition v : vector_of_vectors bool ls :=
        hcons [false; true]
              (hcons []
                     (hcons [true] hnil)).
    End example.
    

    This example uses some notations for vectors that you can set up like this:

    Arguments hnil {_ _}.
    Arguments hcons {_ _ _ _} _ _.
    
    Arguments Vector.nil {_}.
    Arguments Vector.cons {_} _ {_} _.
    
    Delimit Scope vector with vector.
    Bind Scope vector with Vector.t.
    Notation "[ ]" := (@Vector.nil _) : vector.
    Notation "a :: v" := (@Vector.cons _ a _ v) : vector.
    Notation " [ x ] " := (Vector.cons x Vector.nil) : vector.
    Notation " [ x ; y ; .. ; z ] " :=  (Vector.cons x (Vector.cons y .. (Vector.cons z Vector.nil) ..)) : vector.
    
    Open Scope vector.