Tue Dec 27 08:40:17 EST 2011

Multi-dim arrays

Almost ready to integrate in Pd/SM.  Next part is multi-arity
input/output arrays.  The simplest thing to do seems to be to use:

    struct {
        float *a0;
        int *a1;

This seems to involve some type commutation (mapping) of dereference
and structuring (struct of pointer <-> pointer of struct).  Can this
be expressed?

This needs a type class with recursive instances to implement the
recursion over types.

( Is there something like "fold" or "map" for recursive class instances? )

So in essence this doesn't seem hard, but it seems cumbersome and
arbitrary to have to do this with a type class again..

Simply put: what I really want is just an array of structs, so I want
to transform a struct of arrays into something that looks like an
array of structs.  

Wait.  Maybe this can be just another Array instance?

So..  I'm looking for Array and Struct commutation.

How to do this without introducing ambiguity?  I.e. the following
can't work because its head would be the same a proper array of a

  instance (Array m r a t1, 
            Array m r a t2) 
         => Array m r a (t1, t2)

It looks like this needs to be disambiguated by an explicit operation,
otherwise inference will not know what to do and it will need to be
type-annotated anyway..

This is the new (transposing) and old get:

  get' :: r (a t1, a t2) -> r Tint -> m (r (t1, t2))
  get' :: r (Atom (a t)) -> r Tint -> m (r (Atom t))

  get  :: r (a (t1, t2)) -> r Tint -> m (r (t1, t2))
  get  :: r (a (Atom t)) -> r Tint -> m (r (Atom t))
= get  :: r (a t)        -> r Tint -> m (r t)

Note that the last line accomodates both cases of get, but the two
get' cases are structurally different.

After some tinkering:

  class TML m r => SArray m r sa t where
    _get' :: r sa -> r Tint -> m (r t)
    _set' :: r sa -> r Tint -> r t -> m (r ())

  instance (TMLword t,
            Array m r a t,
            StructRepr r,
            TML m r) 
           => SArray m r (Atom (a t)) (Atom t) where 

    _get' r_sa i = do
      (Atom a) <- return $ unatom r_sa
      v        <- _get a i
      return $ atom $ Atom $ v

    _set' r_sa i v = do
      (Atom a) <- return $ unatom r_sa
      (Atom v) <- return $ unatom v
      _set a i v

  instance (SArray m r sa1 t1,
            SArray m r sa2 t2,
            StructRepr r,
            TML m r)
           => SArray m r (sa1, sa2) (t1, t2) where

    _get' r_sa i = do
      (a1, a2) <- return $ uncons r_sa
      v1       <- _get' a1 i
      v2       <- _get' a2 i
      return $ cons (v1, v2)

    _set' r_sa i v = do
      (a1, a2) <- return $ uncons r_sa
      (v1, v2) <- return $ uncons v
      _set' a1 i v1
      _set' a2 i v2