Automatic instance constraints derivation: how?

Hi, I am trying to understand, why do I need to place constraints with class instance declaration while all the information seems to be already available to the compiler. I have placed the code in question here: http://codepad.org/Akew0p2t so anybody can play with it. The code tries to model evaluation of GRIN-style thunks using Haskell type classes instead of tag-based pattern matching, as in the GRIN papers. That is, a thunk is represented as a datatype like data Ffun a b c = Ffun a b c, and there is some "eval" function which being applied to such data results in the call fun a b c. Such "eval" function is a method of class Eval: class Eval a b | a -> b where eval :: (Monad m) => a -> m b which means that thunks of some type (a) evaluate to values of some dependent type (b). The code is monadic because GRIN is a monad, so the code looks similar to GRIN. The ultimate goal is to make GRIN code understandable by Haskell compiler. Everything is fine with "simple" types like Int, that is "instance Eval Int Int" means that Int (and Char, and Bool) do not need in fact evaluation at all. instance Eval Int Int where eval = return Everything is fine with thunks encoding calls to primitives. See instances for FADD and FSUB. All type information for primitives (primPlusInt, primMinusInt) is specified in the code. Then, a function "fun" is defined that calls the primitives. The "main" function illustrates its use, and everything works as expected, as output shows. But when I tried to define a thunk for "fun" (instance for Ffun) I was only able to do that with all constraints on its parameters explicitly set. OTOH, even if I comment out the instance Eval for Ffun, and load the code in Hugs (or GHCi, doesn't matter) then type signature of "fun" is correctly derived by the compiler. If I try to define instance for Ffun like this: instance (Eval x x) => Eval (Ffun a b c) x where eval (Ffun a b c) = fun a b c meaning only the fact that result of the function "fun" will be like Int or Bool - evaluates to itself, and we don't care about the types of arguments, I cannot use forall x. with instance declaration, so I have to say something about x. I get the error (Hugs): Error occurred ERROR line 51 - Instance is more general than a dependency allows *** Instance : Eval (Ffun a b c) d *** For class : Eval a b *** Under dependency : a -> b So, is there a way to define such an instance for a thunk without any constraints? Wouldn't it be reasonable to expect that eval (Ffun a b c) = fun a b c would allow the compiler to retrieve constraints on a, b, c from those already known for the called function? Thanks. -- Dimitry Golubovsky Anywhere on the Web
participants (1)
-
Dimitry Golubovsky