
I was trying to track down the problem with this piece of code: instance (Elt k, IxB a, Eq a, Eq k) => Num (Vector k a) where (+) = vmap2 (+) (-) = vmap2 (-) (*) = vmap2 (*) negate = vmap negate signum = vmap signum abs = vmap abs fromInteger n = vconst $ fromInteger n Vector2.hs:246:0: Could not deduce (Eq (UArray a k)) from the context (Elt k, IxB a, Eq a, Eq k) arising from the superclasses of an instance declaration at Vector2.hs:246:0 Probable fix: add (Eq (UArray a k)) to the instance declaration superclass context or add an instance declaration for (Eq (UArray a k)) In the instance declaration for `Num (Vector k a)' So it appears that here is another barrier to using UArray polymorphically. Am I the first user of this interface? In Data/Array/Base.hs it says: eqUArray :: (IArray UArray e, Ix i, Eq e) => UArray i e -> UArray i e -> Bool eqUArray arr1@(UArray l1 u1 _) arr2@(UArray l2 u2 _) = if rangeSize (l1,u1) == 0 then rangeSize (l2,u2) == 0 else l1 == l2 && u1 == u2 && and [unsafeAt arr1 i == unsafeAt arr2 i | i <- [0 .. rangeSize (l1,u1) - 1]] ... instance Ix ix => Eq (UArray ix Bool) where (==) = eqUArray instance Ix ix => Eq (UArray ix Bool) where (==) = eqUArray instance Ix ix => Eq (UArray ix Char) where (==) = eqUArray instance Ix ix => Eq (UArray ix Int) where (==) = eqUArray instance Ix ix => Eq (UArray ix Word) where (==) = eqUArray ... etc. Why define separate instances when one could just define one equivalent one: instance (Ix ix, Eq e, IArray UArray e) => Eq (UArray ix e) (==) = eqUArray ??? The same question applies to the Ord instances in that file. I can give an answer *why not* do this: it makes UArray even more unusable. UArrays which are polymorphic in their element types cannot be compared. Here is another patch, please apply: --- /home/frederik/ghc-6.4/libraries/base/Data/Array/Unboxed.hs.old 2006-03-12 18:34:14.000000000 +0000 +++ /home/frederik/ghc-6.4/libraries/base/Data/Array/Unboxed.hs 2006-03-12 18:35:32.000000000 +0000 @@ -10,6 +10,9 @@ -- -- Unboxed immutable arrays. -- +-- Beware that these arrays are generally not usable polymorphically +-- because of problems with Eq and Ord instances. +-- ----------------------------------------------------------------------------- module Data.Array.Unboxed ( Confused, Frederik On Sun, Mar 12, 2006 at 02:58:42AM +0000, Frederik Eaton wrote:
I see. The solutions on that thread, i.e.:
http://www.mail-archive.com/haskell%40haskell.org/msg17085.html
would seem to require me to at least declare an instance of some class, for every type that I want to support. So the short answer to "I'm trying to figure out how to use STUArray. Is it possible to let it be polymorphic?" appears to be "No".
Perhaps some sort of warning in the documentation for STUArray is in order, until Bulat's code can be incorporated?
By the way, why make the distinction between unboxable types and "other" types in the first place? E.g., just because I want something to work quickly on "Int", doesn't mean that I don't want it to work at all on "String". It seems that there could be a default "IArray UArray e" instance which just implements a regular Array behind the scenes.
Frederik
On Fri, Mar 10, 2006 at 11:49:10PM +0100, Benjamin Franksen wrote:
On Friday 10 March 2006 23:01, Frederik Eaton wrote:
I'm trying to figure out how to use STUArray. Is it possible to let it be polymorphic?
Hi Frederik
I think this thread (and the one it referres to) provide a solution:
http://www.mail-archive.com/haskell%40haskell.org/msg17081.html
Ben -- There are three kinds of programmers: those who make off by one errors, and those who don't. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hello Frederik, Sunday, March 12, 2006, 9:39:13 PM, you wrote: FE> Why define separate instances when one could just define one FE> equivalent one: FE> instance (Ix ix, Eq e, IArray UArray e) => Eq (UArray ix e) FE> (==) = eqUArray FE> ??? afaik, this is just not H98-compatible and require to use even more type extensions than currently used in this module FE> The same question applies to the Ord instances in that file. FE> I can give an answer *why not* do this: it makes UArray even more FE> unusable. UArrays which are polymorphic in their element types cannot FE> be compared. Here is another patch, please apply: _I_ don't apply the patches, but you can propose patches by sending them to libs maillist. tomorrow Simon Marlow will read it and decide whether it need to be applied most UArrays users don't need polymorphism, i run into problems with arrays only when i wrote general library which should support every array type -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Frederik Eaton wrote:
I was trying to track down the problem with this piece of code:
instance (Elt k, IxB a, Eq a, Eq k) => Num (Vector k a) where (+) = vmap2 (+) (-) = vmap2 (-) (*) = vmap2 (*) negate = vmap negate signum = vmap signum abs = vmap abs fromInteger n = vconst $ fromInteger n
Vector2.hs:246:0: Could not deduce (Eq (UArray a k)) from the context (Elt k, IxB a, Eq a, Eq k) arising from the superclasses of an instance declaration at Vector2.hs:246:0 Probable fix: add (Eq (UArray a k)) to the instance declaration superclass context or add an instance declaration for (Eq (UArray a k)) In the instance declaration for `Num (Vector k a)'
So it appears that here is another barrier to using UArray polymorphically. Am I the first user of this interface?
In Data/Array/Base.hs it says:
eqUArray :: (IArray UArray e, Ix i, Eq e) => UArray i e -> UArray i e -> Bool eqUArray arr1@(UArray l1 u1 _) arr2@(UArray l2 u2 _) = if rangeSize (l1,u1) == 0 then rangeSize (l2,u2) == 0 else l1 == l2 && u1 == u2 && and [unsafeAt arr1 i == unsafeAt arr2 i | i <- [0 .. rangeSize (l1,u1) - 1]]
... instance Ix ix => Eq (UArray ix Bool) where (==) = eqUArray
instance Ix ix => Eq (UArray ix Bool) where (==) = eqUArray
instance Ix ix => Eq (UArray ix Char) where (==) = eqUArray
instance Ix ix => Eq (UArray ix Int) where (==) = eqUArray
instance Ix ix => Eq (UArray ix Word) where (==) = eqUArray ... etc.
Why define separate instances when one could just define one equivalent one:
instance (Ix ix, Eq e, IArray UArray e) => Eq (UArray ix e) (==) = eqUArray
That version certainly compiles without any extra options. It's not H98, but then this library requires MPTC anyway (but not much else, I think). I think Hugs will accept it too. It certainly looks like an improvement, so I'll commit it. Thanks! Cheers, Simon

Excellent. Was it possible to fix Ord as well? Frederik On Mon, Mar 13, 2006 at 02:22:24PM +0000, Simon Marlow wrote:
That version certainly compiles without any extra options. It's not H98, but then this library requires MPTC anyway (but not much else, I think). I think Hugs will accept it too. It certainly looks like an improvement, so I'll commit it. Thanks!
Cheers, Simon
participants (4)
-
Bulat Ziganshin
-
Frederik Eaton
-
Frederik Eaton
-
Simon Marlow