Opened 10 years ago

Closed 10 years ago

# deriving (Ix) and listArray give unexpected results

Reported by: Owned by: guest igloo normal 6.8.3 libraries/base 6.6 scook0@… Unknown/Multiple Unknown/Multiple None/Unknown arr019

### Description

When `arrayList` is used together with a derived instance of `Ix`, the results are not the same as what the Haskell 98 report suggests.

```import Data.Array
import Data.Ix

data Pos = Pos Integer Integer
deriving (Show, Eq, Ord, Ix)

{-
-- copied from the H98 report, with (,) replaced by Pos
instance Ix Pos where
range (Pos l l', Pos u u')
= [ Pos i i' | i <- range (l, u), i' <- range (l', u') ]
index (Pos l l', Pos u u') (Pos i i')
= index (l, u) i * rangeSize (l', u') + index (l', u') i'
inRange (Pos l l', Pos u u') (Pos i i')
= inRange (l, u) i && inRange (l', u') i'
-}

contents = concat \$
[ "ABCD"
, "wxyz"
, "1234"
]

-- example definition of listArray from the H98 report
listArray98 b xs = array b (range b `zip` xs)

array1 = listArray   (Pos 0 0, Pos 2 3) contents
array2 = listArray98 (Pos 0 0, Pos 2 3) contents

main = if array1 == array2
then putStrLn "arrays are equal"
else putStrLn "arrays are NOT equal"
```

In this example, `array1` and `array2` should be equal, but they are not. The `listArray` function interprets its argument list in a different order from `listArray98`.

The underlying problem seems to be that the integer indices produced by the derived `Ix` do not agree with the order implied by `range`, but `listArray` assumes that they do. Replacing either the `Ix` instance or the `listArray` definition with the H98 version gives correct results.

### comment:1 Changed 10 years ago by igloo

difficulty: → Unknown → 6.8.3 set to igloo

```range (l,u) !! index (l,u) i == i   -- when i is in range
```

must hold, but

```Prelude Foo Data.Array> let l = Pos 0 0; u = Pos 2 3; i = Pos 0 1 in range (l,u) !! index (l,u) i == i
False
```

I'll take a look.

### comment:2 Changed 10 years ago by igloo

Test Case: → arr019 bug → merge

```Sun Mar 30 19:28:13 BST 2008  Ian Lynagh <igloo@earth.li>
* Derive a valid Ix instance for data Foo = Foo Int Int
The old one didn't satisfy the axioms. See trac #2158 for details.
```

### comment:3 Changed 10 years ago by igloo

Resolution: → fixed new → closed

Merged

### comment:4 Changed 9 years ago by simonmar

Architecture: Unknown → Unknown/Multiple

### comment:5 Changed 9 years ago by simonmar

Operating System: Unknown → Unknown/Multiple
Note: See TracTickets for help on using tickets.