Hello, The multitude of newtypes in the Monoid module are a good indication that the Monoid class is not a good fit for the class system (it is ironic that discussing it resulted in such a huge thread recently :-). How I'd approach the situation that you describe would depend on the context (did I design the class, or am I just using it? am I writing a library that is to be used by other people, or is the class just used in an internal part of my program?, etc.) but, in general, here are some ideas: 1. If one type can be made into an instance of a class in multipe ways and I have no control over the class: - I would provide non-overloaded versions for each implementation - if there is a "natural" one (something that is quite commonly used) I would use it for an instance - if most uses are equally likely to be useful, then I would not provide an instance but just use the non-overloaded functions. If I did provide an instance, then I would be careful to document the choice I made. 2. If I have control over the class I may consider changing it: - Consider using a different class, that has operations that are more specific to what I am doing (e.g., use a PrettyPrint class instead of Show class) - If many types are members of the same classes, then it may be useful to combine them (i.e., add multiple methods that perform the different operations). I think that I have done all of the above in different situations, and so I don't think that there is a single correct answer. I usually avoid using the "newtype" trick as I find it inconvenient: usually the newtype does not have the same operations as the underlying type and so it cannot be used directly, and if you are going to wrap thing just when you use the class methods, then you may as well use the non-overloaded operations. Hope that this helps, Iavor On Mon, Jan 19, 2009 at 9:40 AM, Patai Gergely <patai_gergely@fastmail.fm> wrote:
As a side curiosity, I would love to see an example of any data structure which has more than one Functor instance. Especially those which have more than one useful functor instance.
data Record a b = R { field1 :: a, field2 :: b }
If I want to use fmap to transform either field, I have to declare the type to have the corresponding type variable at the end, i.e. choosing "Record a b" or "Record b a" is already a design decision, and it is driven by the standard Functor class in this case. I can define custom functions fmap1 and fmap2 manually, but then I don't get the advantages of overloading, like fmapping over a data structure containing my records.
Now I understand that I can't get everything, and my question is mainly what to do when such a dilemma comes up. Those who have already encountered such a dilemma: how did it come up and what did you do to solve it?
Gergely
-- http://www.fastmail.fm - Same, same, but different...
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe