Idris - Displays an operation on an n-dimensional vector

I defined n-dimensional vectors in Idris as follows:

import Data.Vect

NDVect : (Num t) => (rank : Nat) -> (shape : Vect rank Nat) -> (t : Type) -> Type
NDVect Z     []      t = t
NDVect (S n) (x::xs) t = Vect x (NDVect n xs t)

Then I defined the following function, which maps the function f to each entry in the tensor.

iterateT : (f : t -> t') -> (v : NDVect r s t) -> NDVect r s t'
iterateT {r = Z}   {s = []}    f v = f v
iterateT {r = S n} {s = x::xs} f v = map (iterateT f) v

But when I try to call iteratorTin the following function:

scale : Num t => (c : t) -> (v : NDVect rank shape t) -> NDVect rank shape t
scale c v = iterateT (*c) v

I get the following error message indicating that the type is incompatible, which seems very good to me.

 When checking right hand side of scale with expected type
         NDVect rank shape t

 When checking argument v to function Main.iterateT:
         Type mismatch between
                 NDVect rank shape t (Type of v)
         and
                 NDVect r s t (Expected type)

         Specifically:
                 Type mismatch between
                         NDVect rank shape t
                 and
                         NDVect r s t             
         Specifically:
                 Type mismatch between
                         NDVect rank shape t
                 and
                         NDVect r s t
+4
source share
1 answer

I am also interested in how to express n-dimensional vectors (i.e. tensors) in Idris. I had a game with a type definition in the question, but ran into various problems, so I expressed the function NDVectas a data type:

data NDVect : (rank : Nat) -> (shape : Vect rank Nat) -> Type -> Type where
  NDVZ : (value : t) -> NDVect Z [] t
  NDV  : (values : Vect n (NDVect r s t)) -> NDVect (S r) (n::s) t

And the map is implemented as follows:

nmap : (t -> u) -> (NDVect r s t) -> NDVect r s u
nmap f (NDVZ value) = NDVZ (f value)
nmap f (NDV values) = NDV (map (nmap f) values)

It works now:

*Main> NDVZ 5
NDVZ 5 : NDVect 0 [] Integer
*Main> nmap (+4) (NDVZ 5)
NDVZ 9 : NDVect 0 [] Integer
*Main> NDV [NDVZ 1, NDVZ 2, NDVZ 3]
NDV [NDVZ 1, NDVZ 2, NDVZ 3] : NDVect 1 [3] Integer
*Main> nmap (+4) (NDV [NDVZ 1, NDVZ 2, NDVZ 3])
NDV [NDVZ 5, NDVZ 6, NDVZ 7] : NDVect 1 [3] Integer

, . , .

Edit:

, :

data NDVect : (shape : List Nat) -> Type -> Type where
  NDVZ : (value : t) -> NDVect [] t
  NDV  : (values : Vect n (NDVect s t)) -> NDVect (n::s) t

nmap : (t -> u) -> (NDVect s t) -> NDVect s u
nmap f (NDVZ value) = NDVZ (f value)
nmap f (NDV values) = NDV (map (nmap f) values)
0

Source: https://habr.com/ru/post/1690033/


All Articles