
Hello GHC, i has the following function: freezeIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => IOUArray i e -> IO (UArray i e) when i try to use rule: {-# RULES "freeze/IOUArray" freeze = freezeIOUArray #-} the compiler barks. i found the way that compiled: {-# RULES "freeze/IOUArray" forall (x :: (forall s e i . (Unboxed e, HasDefaultValue e) => IOUArray i e)) . freeze x = freezeIOUArray x #-} but is this rule really works? SPJ once mentioned that type checking is just impossible in current rules usage implementation -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

I'm afraid that RULES are applied *after* type checking and dictionary construction. Recall that freeze has type freeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) Your original RULE gives Could not deduce (Unboxed e, HasDefaultValue e) from the context (IArray UArray e, MArray IOUArray e IO, Ix i) arising from use of `freezeIOUArray' at Foo.hs:16:28-41 Probable fix: add (Unboxed e, HasDefaultValue e) to the tcRule When checking the transformation rule "freeze/IOUArray" Why? Because you are trying to rewrite an application freeze dix dma dia ---> freezeIOUArray dunb dhas where dix, dma, dia are dictionaries of type Ix I, MArray IOUArray e m, and IArray b e, respectively. To do the rewrite we need to manufacture dictionaries dunb::Unboxed e and dhas::HasDefaultValue e, respectively. How can we make the latter from the former? We can't. Hence the error message. Your "working" version will generate a rewrite like this: freeze dix dma dia (x dunb dhas) ---> freezeIOUArray dunb dhas x (use -ddump-rules to see the rule that GHC generates). This is a fine rule, but it is most unlikely to match any actual terms! I don't know an easy to way to do what you want. Because you really do need to come up with new dictionaries, and that changes the types. Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users- | bounces@haskell.org] On Behalf Of Bulat Ziganshin | Sent: 21 April 2006 17:42 | To: GHC Users Mailing List | Subject: RULES | | Hello GHC, | | i has the following function: | | freezeIOUArray :: (Unboxed e, HasDefaultValue e, Ix i) => IOUArray i e -> IO (UArray i e) | | when i try to use rule: | | {-# RULES | "freeze/IOUArray" freeze = freezeIOUArray | #-} | | the compiler barks. i found the way that compiled: | | {-# RULES | "freeze/IOUArray" forall (x :: (forall s e i . (Unboxed e, HasDefaultValue e) => IOUArray i e)) . freeze | x = freezeIOUArray x | #-} | | but is this rule really works? SPJ once mentioned that type checking | is just impossible in current rules usage implementation | | | -- | Best regards, | Bulat mailto:Bulat.Ziganshin@gmail.com | | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (2)
-
Bulat Ziganshin
-
Simon Peyton-Jones