Skip to content

The Ix instance for (,) leaks space in range

(at least if you take leak to mean unexpected space behaviour).

This was brought to my attention via http://stackoverflow.com/questions/12780497/puzzling-memory-behavior-in-haskell where someone created a 6×10^6-array and was surprised that showing the array caused an additional (3+2)*8*10^6 bytes to be used. The reason (as far as I could tell) was this code:

instance (Ix a, Ix b) => Ix (a, b) where
    range ((l1,l2),(u1,u2)) = [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]

in Arr.GHC. The result of range (l2,u2) is shared between every step in the first component of the index.

I guess it is reasonable to expect that the result of range is never worth sharing (is it?). I am not entirely sure what the best, cleanest, alternative implementation is, though. (At least not without a working dontshare annotation ;-))

Edited by Ian Lynagh -
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information