plaidfinch / ComonadSheet

A library for expressing "spreadsheet-like" computations with absolute and relative references, using fixed-points of n-dimensional comonads.
MIT License
155 stars 11 forks source link

Representation of indices can lead to nonsense #1

Closed plaidfinch closed 10 years ago

plaidfinch commented 10 years ago

Consider multidimensional spreadsheets. This applies to all higher-dimensional spreadsheets, but we'll examine Z2 here.

We have the following type for two-dimensional zippers:

newtype Z2 c r a = Z2 { fromZ2 :: Z1 r (Z1 c a) }

As such, the column (c) index of each inner Z1 c a is independent. This means that we can do the following:

> let x = pure () :: Z2 Int Int ()
> let y = wrapZ2 (modify zipR) $ x
> col y
1
> col $ zipU $ y
0

This enables us to break an expected invariant of movement in spreadsheets:

> index $ go (atCol 0) y
(0,0)
> index $ go below . go (atCol 0) . go above $ y
(-1,0)

Proposed solution:

Use a new non-indexed list zipper type, and have Z1, Z2, etc. defined in terms of the product of an n-tuple with an n-nested unindexed zipper. This means that there will be a single canonical value for each dimension's index, which means that it will be impossible to break this kind of invariant. This will require significant refactoring, but seems doable.

plaidfinch commented 10 years ago

This issue was solved several iterations back by the representation shift to an unindexed Compose type (now Nested, for other reasons) and an Indexed wrapper. It is now impossible to create problems like this. :)