Defining a statement to access a multidimensional array

I had the idea of ​​defining an operator that accepts a (possibly) multidimensional list and list of indices and returns an element. My attempt:

(!!!) xs [i]            = xs !! i
(!!!) xs (cI : restI)   = (xs !! cI) !!! restI

In retrospect, this obviously has a lot of problems. At first I could not understand the type signature, then I realized that in line 2 the type of the return value (xs !! cI) will constantly change and may not always be a list (at the last "iteration")

I realized that to use a multidimensional array using the standard index operator, you can simply link it like this:

[[1,2,3],[4,5,6],[7,8,9]] !! 1 !! 1 = 5

And I realized that this is very similar to a fold, so I tried:

(!!!) xxs inds = foldl (!!) xxs inds
or simply (!!!) = foldl (!!) 

But I get the same error as my first attempt; that I'm trying to build an infinite type.

( )? , , .

, :

[[1,2,3],[4,5,6],[7,8,9]] !!! [1,1] = 5
+4
1

, . , . :

data Nat = Z | S Nat

infixr 5 :>
data Vector (n :: Nat) a where 
  Nil :: Vector Z a 
  (:>) :: a -> Vector n a -> Vector (S n) a 

(!!!) a Nil = a 
(!!!) a (i :> is) = (a !! i) !!! is 

, . , a . a , , . ; n , n :

type family Dimension (n :: Nat) (v :: * -> *) (x :: *) :: * where 
  Dimension     Z v x = x 
  Dimension (S n) v x = v (Dimension n v x)

(!!!) :: Dimension n [] a -> Vector n Int -> a

, Haskell, .

+8

All Articles