Thanks Ryan. I'm always struggling with functional dependencies since to be honest - I don't really understand how the type inferer figures out all the types and I didn't take the time to study it yet. Your email will help me a bit further with this.
My functional dependency was c -> m v. It can't be m v -> c since for the same model and view type , you can have many controllers types. On Sat, Feb 14, 2009 at 11:38 PM, Ryan Ingram <ryani.s...@gmail.com> wrote: > 2009/2/13 Peter Verswyvelen <bugf...@gmail.com>: > > No the error I got was > > Could not deduce (Controller m v c) > > from the context (Controller m v c2) > > arising from a use of `MVC' at NM8\GUI\PanZoom.hs:126:32-65 > > Possible fix: > > add (Controller m v c) to the context of the constructor `MVC' > > In the expression: MVC m v (PZC s z (unsafeCoerce c)) > > In the definition of `panZoomedMVC'': > > panZoomedMVC' s z (MVC m v c) = MVC m v (PZC s z (unsafeCoerce > c)) > > I got this after adding the type signature of > > panZoomedMVC' :: (Controller m v c, PanZoomable z) => > > State -> z -> MVC m v -> MVC m v > > No function with the type signature of panZoomedMVC' can be called > (unless there is a functional dependency that uniquely determines c > from m and v). It's ambiguous; there's no way to know which instance > to call. > > GHC allows such a function to get an inferred type, but then when it > comes time to call it (and provide the Controller instance) or type > check it against a provided signature, it cannot resolve the ambiguity > and you get that error. > > What is happening in this case is something along these lines: > > 1) Infer a type and constraints for panZoomedMVC': > > Constraints: > Controller t1 t2 t3 > PanZoomable t4 > > Type: > State -> t4 -> MVC t1 t2 -> MVC t1 t2 > > 2) Unify the inferred type signature with your provided signature > > Constraints: > Controller m v t3 > PanZoomable z > > Type: > State -> z -> MVC m v -> MVC m v > > 3) Verify that constraints are sufficient. This fails, because the > use of Controller in the function (Controller m v t3) doesn't match > the use provided by your constraint (Controller m v c). > > However, leaving out the type signature doesn't help you; it just > delays your problem. Because of the ambiguity, panZoomedMVC' cannot > be called; you'll get the error at the callsite instead. > > To solve this problem, either add a dummy argument that fixes "c", or > add a functional dependency or associated type to Controller that > fixes c based on m and v. For example: > > > data Proxy a = Proxy > > panZoomedMVC' :: (Controller m v c, PanZoomable z) => > > Proxy c -> State -> z -> MVC m v -> MVC m v > > panZoomedMVC' _ s z mvc = ... > > Then you can pass the proper "Proxy" when calling the function to make > the typechecker happy. > > or > > > class Controller m v c | m v -> c where ... > > or > > > class Controller m v where > > type Control m v > > ... > > -- ryan >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe