[GHC] #7100: Loosen requirement for free variables in constraint in class declaration
GHC
cvs-ghc at haskell.org
Fri Jul 27 06:27:16 CEST 2012
#7100: Loosen requirement for free variables in constraint in class declaration
------------------------------+---------------------------------------------
Reporter: selinger | Owner:
Type: feature request | Status: new
Priority: normal | Component: Compiler
Version: 7.4.2 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: None/Unknown | Testcase:
Blockedby: | Blocking:
Related: |
------------------------------+---------------------------------------------
In a class declaration, Haskell requires all free variables that occur in
the constraint to also occur as class parameters. Thus, the following is
not allowed:
class MyClass a b | a -> b
instance MyClass Int Bool
instance MyClass a b => MyClass [a] [b]
class MyClass a b => ConvenienceClass a
Note, however, that due to functional dependencies, b is completely
determined by a. There is indeed a workaround that allows the above
ConvenienceClass to be defined. This requires defining a type family to
witness each functional constraint:
type family MyClass_FD_Witness a
class (MyClass_FD_Witness a ~ b) => MyClass a b | a -> b
type instance MyClass_FD_Witness Int = Bool
instance MyClass Int Bool
type instance MyClass_FD_Witness [a] = [MyClass_FD_Witness a]
instance MyClass a b => MyClass [a] [b]
class MyClass a (MyClass_FD_Witness a) => Convenience a
Clearly, whenever there is a functional dependency, it is possible, in the
above way, to define a type family witnessing it. However, the resulting
definitions are very long and cumbersome, particularly if functional
dependencies are composed, or if a dependent variable is used many times
in a constraint.
To illustrate this in a real-life example, here is a line of code that I
have written in an actual application:
class (MonadCurry fun (MonadArgType fun) m a, Curry (CurryType
(MonadArgType fun) String) (MonadArgType fun) String, PrintfType
(CurryType (MonadArgType fun) String)) => WPrintf fun m a
What I really meant to write was:
class (MonadCurry fun arg m a, Curry fun' arg String, PrintfType fun') =>
WPrintf fun m a
The relevant functional dependencies are:
class MonadCurry fun args m res | args m res -> fun, fun -> m args res
class Curry fun args res | args res -> fun
It would be desirable (and, I believe, sound for the above reason) to have
a language option that relaxes the requirement on type variables occurring
in constraints of class declaration, so that each such type variable must
only be reachable from parameters of the class via functional
dependencies.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7100>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list