apfelmus apfelmus at quantentunnel.de
Thu Mar 22 06:15:50 EDT 2007

```Ivan Lazar Miljenovic wrote:
>
> i.e.:
>
> data QLNode a = Null | QLNode a (Right a) (Up a) (Left a)
>                                 (Bottom a)
>
> where Right, Up, Left and Bottom are just type synonyms of QLNode.
>
> You could have only two nodes linked to (e.g. only the right and bottom
> ones), but I've put in four so that if I want to change an element in
> the middle of the matrix, I can do something like in the OOP world, with
> node.previous.next = newNode (not quite sure off the top of my head how
> to do this in Haskell).

As data structures are persistent (you cannot "change" values in place,
you can only create new ones), you'll inevitably run into problems when
updating elements. Assuming a rectangular shape and selector functions

right, up, left, down :: QLNode a -> QLNode a

for the four linked nodes, we have the following equalities (ignoring
the fact that QLNode may be Null)

right . left = left . right = id
down . up    = up . down    = id
right . down = down . right
right . up   = up . right
...
right . up . left . right . down . down = right . down
...

and so on. When updating an element, you'd have to make sure that each
of those equalities still hold. It's possible but takes O(n) time per
element update.

> The advantage I see in this representation is that to access each
> individual row/column is O(n) for an n-by-n matrix.  When I said in my
> initial post that I didn't want an O(n^2) function to get the columns, I
> meant that I didn't want to have to do an O(n^2) transpose function if I
> only wanted to access the kth column.

In case you do not update matrices but build them all at once (say via
some kind of fmap), the quadruply linked list is indeed useful and gives