Hi Conal (and anyone else who is interested!)

:-)

I've got an explanation of your problem, and a workaround!  I'll start
with the latter.

In fact, I found a couple of workarounds, but here is the simplest:

   In the Array.hs library (edit it using :l Array  then :e if you're
   not sure where to find it), replace the line:
            instance (Ix a) => Functor (Array a) where
   with:
            instance Functor (Array a) where

   That's it!  The test program should now load without error!

What's the explanation?  This part is only really going to make a lot
of sense to people who know how the Hugs/Gofer type checker works, but
I'll try anyway.  Because the original version of arrIndexB used the
overloaded map, the principal type that the typechecker infers for the
function has the form:

   (Ix a, Functor (Array a)) => ...

Indeed, that is precisely the type that Gofer would have inferred, and
it is also the type that Hugs 1.4 uses internally ... You'll notice
that this type doesn't match the one you declared for !*.  But, according
to the rules of Haskell, and given that we have an instance declaration:

    instance Ix a => Functor (Array a) where ...

you might well expect the type above to be equivalent to

   (Ix a) => ...

Indeed, this holds in Haskell, but not in Gofer.  If it weren't for the
context part of the instance declaration, it would still hold in Hugs.
But that context effectively tells Hugs that the implementation of
map on arrays may depend on the index type, and so it cannot discharge
the Functor (Array a) constraint until it knows what `a' will be
bound to.  In fact, that (Ix a) constraint is a complete waste of time
because the underlying primitive that implements map on arrays doesn't
make any use of it.  So removing the (Ix a) constraint (a) doesn't
prevent the underlying primitive from working, and (b) allows Hugs to
eliminate any constraint of the form Functor (Array t), without worrying
about what t might be.

In any case, none of this is necessary with the new typechecker, which
follows the rules of Haskell, and which doesn't need the fix.

Hope this helps!

All the best,
Mark

Reply via email to