Skip to content

deriving (Ix) and listArray give unexpected results

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.

Trac metadata
Trac field Value
Version 6.6
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC scook0@gmail.com
Operating system Unknown
Architecture Unknown
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information