On 29/03/2007, at 11:38, Mike Hamburg wrote:
Is there any way to use RULES substitutions with type classes?
I'm writing a reactive programming arrow (same idea as Yampa, different design goals), and it would help performance (and not just in the speed sense) to be able to tell when a value derived with arr hasn't changed. So I'd like to be able to specialize arr to functions whose result is an instance of Eq.
I tried {-# RULES "reactiveArr/Eq" reactiveArr = reactiveArrEq #-} but got the message
Control/Arrow/Reactive/Reactive.hs:89:41: No instance for (Eq b) arising from instantiating a type signature at Control/Arrow/Reactive/Reactive.hs:89:41-89 Possible fix: add (Eq b) to the tcRule When checking the transformation rule "reactiveArr/Eq"
I tried adding various sorts of type signatures, but I couldn't find any way around this... is it a restriction in the RULES rewrite engine? Is there a workaround, or some mechanism other than RULES that I should be using? I could write a special "arrEq" function, but I'd like to minimize the number of extraneous operations outside the Arrow class.
I thought this could be done already. In ghc 6.7: \begin{code} {-# RULES "hello/helloBool" hello = helloBool #-} {-# RULES "hello/helloEq" forall (x::Eq a=>a) . hello x = helloEq x #-} {-# RULES "hello/helloF" forall (f::Eq b=>a->b) . hello f = helloF f #-} data O = O hello _ = "hello" helloBool :: Bool -> String helloBool _ = "hello bool" helloEq :: Eq a => a -> String helloEq _ = "hello Eq" helloF :: Eq b => (a->b) -> String helloF _ = "hello F" f :: Eq b => String -> b f = undefined normal = hello O bool = hello False char = hello 'a'feq :: String feq = hello (f::String -> Bool) \end{code} pep:~/code/snippets$ ghc -O -fglasgow-exts -c rules.hs pep:~/code/snippets$ ghci rules.hs ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.7.20070303, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. [1 of 1] Skipping Rules ( rules.hs, rules.o ) Ok, modules loaded: Rules. Prelude Rules> normal "hello" Prelude Rules> bool "hello bool" Prelude Rules> char "hello Eq" Prelude Rules> feq "hello F" Is that what you wanted? pepe