Partially applied type class functions
Hello, I have encountered a type error that I find quite puzzling. I would appreciate it if someone could help me understand what is going wrong. Here is the program:
data Expr = Var String | Const Int data Constraint = Zero Expr | AndL Constraint
class AbSyn a where subst :: Expr -> String -> a -> a
instance AbSyn Expr where subst e n expr = expr
instance AbSyn Constraint where subst e n constr = let sub = subst e n -- :: AbSyn a => a -> a in case constr of Zero expr -> Zero (sub expr) AndL cs -> AndL (sub cs)
GHC 6.4 (as well as Hugs March 2005) produces this error: Couldn't match `Constraint' against `Expr' Expected type: Constraint Inferred type: Expr In the application `sub cs' In the first argument of `AndL', namely `(sub cs)' If I replace the last line with this one, everything is fine: AndL cs -> AndL (subst e n cs) It looks sort of like sub is being monomorphised -- or something? Thanks for having a look, Paul
Paul Govereau wrote: [snip]
instance AbSyn Constraint where subst e n constr = let sub = subst e n -- :: AbSyn a => a -> a in case constr of Zero expr -> Zero (sub expr) AndL cs -> AndL (sub cs)
It looks sort of like sub is being monomorphised -- or something?
I think you just hit the monomorphism restriction. For the details, see: http://www.haskell.org/onlinereport/decls.html - Sect. 4.5.5 http://haskell.org/hawiki/MonomorphismRestriction Possible solutions for your specific case are: 1) add an explicit type signature for sub let sub :: AbSyn a => a -> a sub = subst e n in ... 2) eta-expand sub, so its definition becomes a function binding let sub c = subst e n c in ... Regards, Roberto Zunino.
Hello, On 8/5/05, Paul Govereau <govereau@eecs.harvard.edu> wrote:
Hello,
I have encountered a type error that I find quite puzzling. I would appreciate it if someone could help me understand what is going wrong. Here is the program:
data Expr = Var String | Const Int data Constraint = Zero Expr | AndL Constraint
class AbSyn a where subst :: Expr -> String -> a -> a
instance AbSyn Expr where subst e n expr = expr
instance AbSyn Constraint where subst e n constr = let sub = subst e n -- :: AbSyn a => a -> a in case constr of Zero expr -> Zero (sub expr) AndL cs -> AndL (sub cs)
GHC 6.4 (as well as Hugs March 2005) produces this error:
Couldn't match `Constraint' against `Expr' Expected type: Constraint Inferred type: Expr In the application `sub cs' In the first argument of `AndL', namely `(sub cs)'
If I replace the last line with this one, everything is fine:
AndL cs -> AndL (subst e n cs)
It looks sort of like sub is being monomorphised -- or something?
This is exactly right, you have encountered the 'monomorphism restriction'. It says that definitions that do not syntactically look like functions (i.e. they don't have arguments) should not be overloaded, unless the programmer provides an explicit type signature. You can fix your program by: (i) adding an argument to 'sub' to make it look like a function: sub x = subst e n x -- :: AbSyn a => a -> a (ii) write the type signature explicitly to indicate that you are aware of the overloading: sub :: AbSyb a => a -> a sub = subst e n This rule was introduced to avoid accidental loss sharing. You can read more about it at the Haskell wiki, although the author of the article was quite clearly against the monomorphism restriction :-) http://www.haskell.org/hawiki/MonomorphismRestriction -Iavor
Finally a plain English explanation of the silly thing. Thank you! I tried reading the Haskell report's version of it, and yes I'm sure it has all the gory technical details, but at the end I was still left thinking So exactly what is the monomorphism restriction? Why on earth couldn't they have added a simple one line explanation like this? cheers "Iavor Diatchki" <iavor.diatchki@gmail.com> wrote in message news:5ab17e7905080511062e3797b0@mail.gmail.com... Hello, This is exactly right, you have encountered the 'monomorphism restriction'. It says that definitions that do not syntactically look like functions (i.e. they don't have arguments) should not be overloaded, unless the programmer provides an explicit type signature. -Iavor
On 07/08/2005, at 12:47 AM, Srinivas Nedunuri wrote:
Finally a plain English explanation of the silly thing. Thank you! I tried reading the Haskell report's version of it, and yes I'm sure it has all the gory technical details, but at the end I was still left thinking So exactly what is the monomorphism restriction? Why on earth couldn't they have added a simple one line explanation like this?
If you're using GHC, a possibly very simple solution to your program is to add the -fno-monomorphism-restriction flag to the compilation, and pray you don't run into another type error ;) -- % Andre Pang : trust.in.love.to.save <http://www.algorithm.com.au/>
participants (5)
-
Andre Pang -
Iavor Diatchki -
Paul Govereau -
Roberto Zunino -
Srinivas Nedunuri