Re: [Haskell-cafe] Factoring into type classes
Hello again, 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. Yes, I had the same thought. If I have to explicitly convert between various wrappers, that's basically the same as defining separate functions from the start. The newtype trick is certainly nice when you don't want to mix the different uses on the same piece of data, but that was exactly my problem. I'd say your posts as well as wren ng thornton's answer my question as thoroughly as possible at this point, although wren's lengthy letter could probably even be extended and turned into a tutorial on the topic. Of course type classes are not only important just for making dictionary passing implicit, but also because of their interactions, which is nicely demonstrated by the sigfpe blog entry that someone also linked from this thread. That's probably why I feel kind of uncomfortable when not taking advantage of standard classes wherever possible. Thanks for the answers, Gergely -- http://www.fastmail.fm - Access all of your messages and folders wherever you are ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Hi folks I have been known to venture the viewpoint that the newtype trick might benefit from improved library support, for example, here http://www.mail-archive.com/haskell-cafe@haskell.org/msg37213.html This is in a similar vein to Derek's approach, if accompanied by a little more grotesque whizzbangery. On 19 Jan 2009, at 21:51, Derek Elkins wrote: On Mon, 2009-01-19 at 12:10 -0800, Iavor Diatchki wrote: Sure, the point is that you are essentially adding a type annotation, which is like using a non-overloaded function. Compare, for example: mappend add x y and getSum (mappend (Sum x) (Sum y)). I think that the first one is quite a bit more readable but, of course, this is somewhat subjective. data Iso a b = Iso { to :: a - b, from :: b - a } under :: Iso a b - (b - b) - (a - a) under iso = to iso ~ from iso under2 :: Iso a b - (b - b - b) - (a - a - a) under2 iso = to iso ~ under iso sumIso = Iso Sum getSum (+) = under2 sumIso mappend Perhaps it's worth trying to push in this direction, in search of a coherent kit. After all, there's a lot of structure out there. All the best Conor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Hello, I don't mean to be negative here but I really fail to see how do any of these ideas help the situation. (I do think it would be cool to have a generic way to lift functions from one type to another that is isomorphic to it). The fundamental problem is that there are multiple functions of type Int - Int - Int (Int being just an example, for the sake of concreteness), that can be the binary operation of a monoid. Therefore, we cannot use the type system to determine how to resolve the overloading of symbols like mappend. Monoids are general enough so that many types have multiple monoidal structure, which is why I wrote that I don't think that they are good match for the class system. Defining a newtype and passing around isomorphisms seems more complex to me than simply passing around the operations directly (i.e., not using the class system). By the way, Miguel's preference can be coded almost verbatim in ML using local declarations (I am referring to the let-like construct that allows the definition of local values that scope over multiple declarations) without any fancy type magic. -Iavor On Tue, Jan 20, 2009 at 8:42 AM, Conor McBride co...@strictlypositive.org wrote: Hi folks I have been known to venture the viewpoint that the newtype trick might benefit from improved library support, for example, here http://www.mail-archive.com/haskell-cafe@haskell.org/msg37213.html This is in a similar vein to Derek's approach, if accompanied by a little more grotesque whizzbangery. On 19 Jan 2009, at 21:51, Derek Elkins wrote: On Mon, 2009-01-19 at 12:10 -0800, Iavor Diatchki wrote: Sure, the point is that you are essentially adding a type annotation, which is like using a non-overloaded function. Compare, for example: mappend add x y and getSum (mappend (Sum x) (Sum y)). I think that the first one is quite a bit more readable but, of course, this is somewhat subjective. data Iso a b = Iso { to :: a - b, from :: b - a } under :: Iso a b - (b - b) - (a - a) under iso = to iso ~ from iso under2 :: Iso a b - (b - b - b) - (a - a - a) under2 iso = to iso ~ under iso sumIso = Iso Sum getSum (+) = under2 sumIso mappend Perhaps it's worth trying to push in this direction, in search of a coherent kit. After all, there's a lot of structure out there. All the best Conor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Luke Palmer wrote: On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fmwrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. There are plenty of data structures which are multi-functors--- namely any type constructor with multiple arguments. The choice of order for arguments to the type constructor is arbitrary, so you can trivially choose the order you need for the Functor instance you want. Depending on intensional vs extensional definitions for types, some may argue that these are different types due to currying and kinding issues, but those concerns only highlight the limitations of not having type-level functions like `flip`, rather than having any category theoretic basis. -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Patai Gergely wrote: Hi everyone, I have a general program design question, but I can't really think of good examples so it will be a bit vague. There was a discussion on Show not long ago which brought up the problem that there are several ways to show a data structure, and it depends on the context (or should I call it a use case?) which of these we actually want, e.g. human readable form, debug information, serialisation for later reading and so on, and one of the solutions was to propose a family of show functions that carry the intended use in their name. However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, what should one do? Should one refrain from instantiating these classes altogether and just use the names of operations directly? If one still decides to pick a certain set of operations as an instance, what are the factors that should guide this decision? What about designing libraries, how much should one prefer standard classes for their interfaces? It seems to me that there is practically no literature on design issues like these, and it would be nice to hear some opinions from experienced Haskellers. As others have mentioned or alluded to, I think that if you're designing general functions where you anticipate running into these issues then you should avoid the instance-selection mechanism of type classes. You can still use the dictionary-passing idea of type classes, but you must pass the dictionaries explicitly. This approach is used by the generalized functions in Data.List[1], as well as many other places. Dictionary passing is, in essence, what higher-order programming is all about. Most often we deal with degenerate cases of dictionary passing where we only pass a single function (e.g. Data.List), but that's not the only way. Another place where dictionary passing is used extensively is in the category-extras package[2] where the dictionaries are called F-(co)algebras. An F-algebra is still degenerate as dictionaries go (it's a single function :: f a - a), but it can be insightful to consider it as a dictionary proper, for example with folding functions like foldr. Normally we look at the type of foldr and think of it as taking two arguments, one for each constructor of lists. Instead, we can use a case expression to pack those two arguments together into a single F-algebra, selecting which argument to return based on the constructor. And this can be generalized to the folding functions for any datatype. Thus, it's helpful to think of dictionaries as algebras (in generic and universal terms). A monoid is just one example of an object in universal algebra, it is an algebra defined by the underlying type, the operator, and the identity. Any type class is also an example of an algebra (e.g. Num defines an algebra with addition, multiplication, etc; Show is an algebra for showing). We can package any algebra up into a record and then pass that record around to the generic functions which need to use an instance of the algebra. The same idea can be used for passing around laws and proofs about data types (e.g. any function of type F(G a) - G(F a) is a law that says we can distribute F over G). The only difference between using type classes and manually passing these records around is that Haskell has linguistic and runtime support for plucking the records out of the aether based on types. Since the compiler knows about type classes it can do smarter things for them than just passing dictionaries, so they should be used whenever reasonable. Type classes are wonderful, but they're not a silver bullet. Even when they're not reasonable, having first-class functions means we're not limited by their restrictions. [1] http://cvs.haskell.org/Hugs/pages/libraries/base/Data-List.html#22 [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/category-extras -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Factoring into type classes
Hi everyone, I have a general program design question, but I can't really think of good examples so it will be a bit vague. There was a discussion on Show not long ago which brought up the problem that there are several ways to show a data structure, and it depends on the context (or should I call it a use case?) which of these we actually want, e.g. human readable form, debug information, serialisation for later reading and so on, and one of the solutions was to propose a family of show functions that carry the intended use in their name. However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, what should one do? Should one refrain from instantiating these classes altogether and just use the names of operations directly? If one still decides to pick a certain set of operations as an instance, what are the factors that should guide this decision? What about designing libraries, how much should one prefer standard classes for their interfaces? It seems to me that there is practically no literature on design issues like these, and it would be nice to hear some opinions from experienced Haskellers. Gergely -- http://www.fastmail.fm - The way an email service should be ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
As for multiple Monoid or Functor instances, simply define a newtype, as it is done in Data.Monoid. What part of your question does that answer and what part doesn't it? 2009/1/19 Patai Gergely patai_gerg...@fastmail.fm: Hi everyone, I have a general program design question, but I can't really think of good examples so it will be a bit vague. There was a discussion on Show not long ago which brought up the problem that there are several ways to show a data structure, and it depends on the context (or should I call it a use case?) which of these we actually want, e.g. human readable form, debug information, serialisation for later reading and so on, and one of the solutions was to propose a family of show functions that carry the intended use in their name. However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, what should one do? Should one refrain from instantiating these classes altogether and just use the names of operations directly? If one still decides to pick a certain set of operations as an instance, what are the factors that should guide this decision? What about designing libraries, how much should one prefer standard classes for their interfaces? It seems to me that there is practically no literature on design issues like these, and it would be nice to hear some opinions from experienced Haskellers. Gergely -- http://www.fastmail.fm - The way an email service should be ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fmwrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
2009/1/19 Luke Palmer lrpal...@gmail.com: 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. (,) ? -Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
2009/1/19 Luke Palmer lrpal...@gmail.com: On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fm wrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. Luke The recent, and great, blog post about moniods [1] discusses the fact that (Num a) could be one of several different monoids and how that was handled. [1] http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Am Montag, 19. Januar 2009 14:31 schrieb Antoine Latter: 2009/1/19 Luke Palmer lrpal...@gmail.com: 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. (,) ? -Antoine Wrong kind. And (,) a has only one useful instance. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Am Montag, den 19.01.2009, 14:47 +0100 schrieb Daniel Fischer: Am Montag, 19. Januar 2009 14:31 schrieb Antoine Latter: 2009/1/19 Luke Palmer lrpal...@gmail.com: 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. (,) ? -Antoine Wrong kind. And (,) a has only one useful instance. What about instance Functor ((,) a) where fmap f (x,y) = (x, f y) and instance Functor (, a) where fmap f (x, y) = (f x, y) ? Of course, the latter is not legal Haskell. But if it was, then it might be useful. Is there any way to declare this Functor instance, possibly with some GHC extensions? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
The desugaring of (, a) would involve some type level lambda, and that's not something that is available (yet). -- Lennart On Mon, Jan 19, 2009 at 1:49 PM, Holger Siegel holgersiege...@yahoo.de wrote: Am Montag, den 19.01.2009, 14:47 +0100 schrieb Daniel Fischer: Am Montag, 19. Januar 2009 14:31 schrieb Antoine Latter: 2009/1/19 Luke Palmer lrpal...@gmail.com: 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. (,) ? -Antoine Wrong kind. And (,) a has only one useful instance. What about instance Functor ((,) a) where fmap f (x,y) = (x, f y) and instance Functor (, a) where fmap f (x, y) = (f x, y) ? Of course, the latter is not legal Haskell. But if it was, then it might be useful. Is there any way to declare this Functor instance, possibly with some GHC extensions? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
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
Re: [Haskell-cafe] Factoring into type classes
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_gerg...@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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
On Mon, 2009-01-19 at 10:59 -0800, Iavor Diatchki wrote: 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 I would say rather that the class system is not a good fit for Monoid. Proposals for local instances, multiple instances, instance import/export control, etc. come up quite frequently on this list; the phenomena in question are not restricted to Monoid. 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, OTOH, I think you mean here `when you use class methods and when you use overloaded functions'. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
Hi, On Mon, Jan 19, 2009 at 11:06 AM, Jonathan Cast jonathancc...@fastmail.fm wrote: On Mon, 2009-01-19 at 10:59 -0800, Iavor Diatchki wrote: 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 I would say rather that the class system is not a good fit for Monoid. Proposals for local instances, multiple instances, instance import/export control, etc. come up quite frequently on this list; the phenomena in question are not restricted to Monoid. I disagree with you but that is a moot point because we are discussing Haskell, which does not have any of these features. Also, I find that in many situations where people want to use them, simpler solutions (like some of the ideas I mentioned in my previous post) suffice. That is not to say that we should stop trying to figure out how to improve the class system, but language changes require a lot more work than improving the design of the libraries. 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, OTOH, I think you mean here `when you use class methods and when you use overloaded functions'. Sure, the point is that you are essentially adding a type annotation, which is like using a non-overloaded function. Compare, for example: mappend add x y and getSum (mappend (Sum x) (Sum y)). I think that the first one is quite a bit more readable but, of course, this is somewhat subjective. -Iavor ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
This is one of the shortcomings of haskell not to mention other programming languages. Mathemathicist would find it very annoying. Instead of instance Monoid Integer where mappend = (+) mempty = 0 instance Monoid Integer where mappend = (*) mempty = 1 which is not legal and the workaround Num a = Monoid (Sum a) Num a = Monoid (Product a) wich is cumbersome A mathematician would say something like: instance Monoid Integer with operation + where mappend = (+) mempty = 0 and instance Monoid Integer with operation * where mappend = (*) mempty = 1 But talking about shortcomings, personally I prefer to implement first a form of assertion that permits the checking of the class properties automatically for each new instance. This is far more important in práctical terms. 2009/1/19 Thomas DuBuisson thomas.dubuis...@gmail.com 2009/1/19 Luke Palmer lrpal...@gmail.com: On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fm wrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. Luke The recent, and great, blog post about moniods [1] discusses the fact that (Num a) could be one of several different monoids and how that was handled. [1] http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
On Mon, 2009-01-19 at 12:10 -0800, Iavor Diatchki wrote: 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, OTOH, I think you mean here `when you use class methods and when you use overloaded functions'. Sure, the point is that you are essentially adding a type annotation, which is like using a non-overloaded function. Compare, for example: mappend add x y and getSum (mappend (Sum x) (Sum y)). I think that the first one is quite a bit more readable but, of course, this is somewhat subjective. Right. Of course, this issue comes up quite frequently; even sort :: Ord alpha = [alpha] - [alpha] Needs to be specialized to non-standard Ord instances. I think that, if we're going to restrict type classes to only those cases where we never want to specialize an overloaded function to a non-standard instance, that we're going to end up with Eq, Num, and maybe Functor as classes. I'm not sure a general language mechanism is really needed just for those three. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
On Mon, 2009-01-19 at 21:18 +0100, Alberto G. Corona wrote: This is one of the shortcomings of haskell not to mention other programming languages. Mathemathicist would find it very annoying. Instead of instance Monoid Integer where mappend = (+) mempty = 0 instance Monoid Integer where mappend = (*) mempty = 1 which is not legal and the workaround Num a = Monoid (Sum a) Num a = Monoid (Product a) wich is cumbersome A mathematician would say something like: instance Monoid Integer with operation + where mappend = (+) mempty = 0 and instance Monoid Integer with operation * where mappend = (*) mempty = 1 Check out the OBJ family of languages, particularly OBJ3 and (I think) Maude. But talking about shortcomings, personally I prefer to implement first a form of assertion that permits the checking of the class properties automatically for each new instance. This is far more important in práctical terms. 2009/1/19 Thomas DuBuisson thomas.dubuis...@gmail.com 2009/1/19 Luke Palmer lrpal...@gmail.com: On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fm wrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. Luke The recent, and great, blog post about moniods [1] discusses the fact that (Num a) could be one of several different monoids and how that was handled. [1] http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
I'd prefer something like Sum :: Monoid Integer Sum = Monoid {mappend = (+), mempty = 0} Prod :: Monoid Integer Prod = Monoid {mappend = (*), mempty = 1} instance Sum in [some code using mempty and mappend] On 19 Jan 2009, at 23:18, Alberto G. Corona wrote: This is one of the shortcomings of haskell not to mention other programming languages. Mathemathicist would find it very annoying. Instead of instance Monoid Integer where mappend = (+) mempty = 0 instance Monoid Integer where mappend = (*) mempty = 1 which is not legal and the workaround Num a = Monoid (Sum a) Num a = Monoid (Product a) wich is cumbersome A mathematician would say something like: instance Monoid Integer with operation + where mappend = (+) mempty = 0 and instance Monoid Integer with operation * where mappend = (*) mempty = 1 But talking about shortcomings, personally I prefer to implement first a form of assertion that permits the checking of the class properties automatically for each new instance. This is far more important in práctical terms. 2009/1/19 Thomas DuBuisson thomas.dubuis...@gmail.com 2009/1/19 Luke Palmer lrpal...@gmail.com: On Mon, Jan 19, 2009 at 3:58 AM, Patai Gergely patai_gerg...@fastmail.fm wrote: However, there are other type classes that are too general to assign such concrete uses to. For instance, if a data structure can have more than one meaningful (and useful) Functor or Monoid instance, 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. Luke The recent, and great, blog post about moniods [1] discusses the fact that (Num a) could be one of several different monoids and how that was handled. [1] http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Factoring into type classes
On Mon, 2009-01-19 at 12:10 -0800, Iavor Diatchki wrote: Hi, On Mon, Jan 19, 2009 at 11:06 AM, Jonathan Cast jonathancc...@fastmail.fm wrote: On Mon, 2009-01-19 at 10:59 -0800, Iavor Diatchki wrote: 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 I would say rather that the class system is not a good fit for Monoid. Proposals for local instances, multiple instances, instance import/export control, etc. come up quite frequently on this list; the phenomena in question are not restricted to Monoid. I disagree with you but that is a moot point because we are discussing Haskell, which does not have any of these features. Also, I find that in many situations where people want to use them, simpler solutions (like some of the ideas I mentioned in my previous post) suffice. That is not to say that we should stop trying to figure out how to improve the class system, but language changes require a lot more work than improving the design of the libraries. 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, OTOH, I think you mean here `when you use class methods and when you use overloaded functions'. Sure, the point is that you are essentially adding a type annotation, which is like using a non-overloaded function. Compare, for example: mappend add x y and getSum (mappend (Sum x) (Sum y)). I think that the first one is quite a bit more readable but, of course, this is somewhat subjective. data Iso a b = Iso { to :: a - b, from :: b - a } under :: Iso a b - (b - b) - (a - a) under iso = to iso ~ from iso under2 :: Iso a b - (b - b - b) - (a - a - a) under2 iso = to iso ~ under iso sumIso = Iso Sum getSum (+) = under2 sumIso mappend ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe