
Dear Haskellers, I've a question about type class design. When developing the set of functions for a class, there are often two or more functions, let's say f and g, where the semantics of g can be expressed by f. When writing down the code, there are two choices for g. First g is included in the type class, second g is defined outside and the signature has a context referencing the class. 1. case class Foo a where f :: ... a ... g :: ... a ... g = expr[f] 2. case class Foo a where f :: ... a ... g :: Foo a => ... a ... g = expr[f] What are the reasons for choosing 1., what are the arguments for 2.? My arguments for 1.: a) Efficiency: g may be overwritten in an instance declaration by a more efficient piece of code. b) Readability: All functions, which are logically connected are grouped together in a single syntactic construct and can be found in one place (similar to an interface in Java). My argument for 2.: c) Correctness: The semantics for g are fix (relative to f), All laws for g hold everywhere, assuming f is implemented correctly. I've sometimes the problem to balance the reasons for 1. and 2 and I doubt, that this list of criteria is complete. In the standard Haskell classes we can find both cases, even within a single class. Eq with (==) as f and (/=) as g belongs to the 1. case, so does Monad and (>>=) as f and (>>) as g. But (>=>) and the Monad class fall into the 2. case. It seem, there is no uniform or consistent strategy in the core Haskell classes. What are your best practice rules for this problem? Expecting your advices, Uwe