Re: In hoc signo vinces (Was: Revamping the numeric classes)
In a later posting Marcin Kowalczyk says: If (+) can be implicitly lifted to functions, then why not signum? Note that I would lift neither signum nor (+). I don't feel the need. ... On Mon, Feb 12, 2001 at 09:33:03AM +, Jerzy Karczmarczuk wrote: I not only feel the need, but I feel that this is important that the additive structure in the codomain is inherited by functions. In a more specific context: the fact that linear functionals over a vector space form also a vector space, is simply *fundamental* for the quantum mechanics, for the cristallography, etc. You don't need to be a Royal Abstractor to see this. I see this in a somewhat different light, though I'm in general agreement. What I'd like to do is to be able to effectively model module structures in the type system, and furthermore be able to simultaneously impose distinct module structures on a particular type. For instance, complex n-vectors are simultaneously C-modules and R-modules. and an arbitrary commutative ring R is at once a Z-module and an R-module. Linear functionals, which seem like common beasts (try a partially applied inner product) live in the mathematical structure Hom_R(M,R) which is once again an R-module, and, perhaps, by inheriting structure on R, an R' module from various R'. So how does this affect Prelude design? Examining a small bit of code could be helpful: -- The group must be Abelian. I suppose anyone could think of this. class (AdditiveGroup g, Ring r) = LeftModule g r where () :: r - g - g instance AdditiveGroup g = LeftModule g Integer where n x | n == 0 = one | n 0 = -(n (-x)) | n 0 = x + (n-1) x ... and we naturally acquire the sort of structure we're looking for. But this only shows a possible outcome, and doesn't motivate the implementation. What _will_ motivate the implementation is the sort of impact this has on various sorts of code: (1) The fact that R is an AdditiveGroup immediately makes it a Z-module, so we have mixed-mode arithmetic by a different means from the usual implicit coercion. (2) This sort of business handles vectors quite handily. (3) The following tidbit of code immediately handles curried innerprods: instance (AdditiveGroup group, Ring ring) = LeftModule (group-ring) ring where r g = \g' - r g g' (4) Why would we want to curry innerprods? I envision: type SurfaceAPoles foo = SomeGraph (SomeVector foo) and then surface :: SurfaceAPoles bar innerprod v `fmap` normalsOf faces where faces = facesOf surface (5) Why would we want to do arithmetic on these beasts now that we think we might need them at all? If we're doing things like determining the light reflected off of the various surfaces we will want to scale and add together the various beasties. Deferring the innerprod operation so we can do this is inelegant and perhaps inflexible compared to: lightSources :: [(SomeVector foo - Intensity foo, Position)] lightSources = getLightSources boundingSomething reflection = sum $ map (\(f,p) - getSourceWeight p * f) lightSources reflection `fmap` normalsOf faces where faces = facesOf surface and now in the lightSources perhaps ambient light can be represented very conveniently, or at least the function type serves to abstract out the manner in which the orientation of a surface determines the amount of light reflected off it. (My apologies for whatever inaccuracies are happening with the optics here, it's quite far removed from my direct experience.) Furthermore, within things like small interpreters, it is perhaps convenient to represent the semantic values of various expressions by function types. If one should care to define arithmetic on vectors and vector functions in the interpreted language, support in the source language allows a more direct approach. This would arise within solid modelling and graphics once again, as little languages are often used to describe objects, images, and the like. How can we anticipate all the possible usages of pretty-looking vector and matrix algebra? I suspect graphics isn't the only place where linear algebra could arise. All sorts of differential equation models of physical phenomena, Markov models of state transition systems, even economic models at some point require linear algebra in their computational methods. It's something I at least regard as a fairly fundamental and important aspect of computation. And to me, that means that the full power of the language should be applied toward beautifying, simplifying, and otherwise enabling linear algebraic computations. Cheers, Bill P.S.: Please forgive the harangue-like nature of the post, it's the best I could do at 3AM. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: In hoc signo vinces (Was: Revamping the numeric classes)
On Mon, 12 Feb 2001, Jerzy Karczmarczuk wrote: I not only feel the need, but I feel that this is important that the additive structure in the codomain is inherited by functions. It could support only the basic arithmetic. It would not automatically lift an expression which uses () and if. It would be inconsistent to provide a shortcut for a specific case, where generally it must be explicitly lifted anyway. Note that it does make sense to lift () and if, only the type system does not permit it implicitly because a type is fixed to Bool. Lifting is so easy to do manually that I would definitely not constrain the whole Prelude class system only to have convenient lifting of basic arithmetic. When it happens that an instance of an otherwise sane class for functions makes sense, then OK, but nothing more. -- Marcin 'Qrczak' Kowalczyk ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: In hoc signo vinces (Was: Revamping the numeric classes)
On Mon, 12 Feb 2001, Jerzy Karczmarczuk wrote: I want to be *able* to define mathematical operations upon objects which by their intrinsic nature permit so! You can't do it in Haskell as it stands now, no matter what the Prelude would be. For example I would say that with the definition abs x = if x = 0 then x else -x it's obvious how to obtain abs :: ([Int]-Int) - ([Int]-Int): apply the definition pointwise. But it will never work in Haskell, unless we changed the type rules for if and the tyoe of the result of (=). You are asking for letting abs x = max x (-x) work on functions. OK, in this particular case it can be made to work by making appropriate instances, but it's because this is a special case where all intermediate types are appropriately polymorphic. This technique cannot work in general, as the previous example shows. So IMHO it's better to not try to pretend that functions can be implicitly lifted. Better provide as convenient as possible way of manual lifting arbitrary functions, so it doesn't matter if they have fixed Integer in the result or not. You are asking for an impossible thing. I defined hundred times some special functions to add lists or records, to multiply a tree by a scalar (btw.: Jn Fairbarn proposes (.*), I have in principle nothing against, but these operators is used elsewhere, in other languages, CAML and Matlab; I use (*) ). Please show a concrete proposal how Prelude classes could be improved. -- Marcin 'Qrczak' Kowalczyk ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: In hoc signo vinces (Was: Revamping the numeric classes)
Marcin Kowalczyk continues: On Mon, 12 Feb 2001, Jerzy Karczmarczuk wrote: I want to be *able* to define mathematical operations upon objects which by their intrinsic nature permit so! You can't do it in Haskell as it stands now, no matter what the Prelude would be. For example I would say that with the definition abs x = if x = 0 then x else -x it's obvious how to obtain abs :: ([Int]-Int) - ([Int]-Int): apply the definition pointwise. But it will never work in Haskell, unless we changed the type rules for if and the tyoe of the result of (=). You are asking for letting abs x = max x (-x) work on functions. OK, in this particular case it can be made to work Why don't you try from time to time to attempt to understand what other people want? And wait, say 2 hours, before responding? I DON'T WANT max TO WORK ON FUNCTIONS. I never did. I will soon (because I am writing a graphical package where max serves to intersect implicit graphical objects) need that, but for very specific functions which represent textures, but NOT in general. I repeat for the last time, that I want to have those operations which are *implied* by the mathematical properties. And anyway, if you replace x=0 by x=zero with an appropriate zero, this should work as well. I want only that Prelude avoids spurious dependencies. This is the way I program in Clean, where there is no Num, and (+), (*), zero, abs, etc. constitute classes by themselves. So, when you say: You are asking for an impossible thing. My impression is what is impossible, is your way of interpreting/ understanding the statements (and/or desiderata) of other people. I defined hundred times some special functions to add lists or records, to multiply a tree by a scalar (btw.: Jn Fairbarn proposes (.*), I have in principle nothing against, but these operators is used elsewhere, in other languages, CAML and Matlab; I use (*) ). Please show a concrete proposal how Prelude classes could be improved. (Why do you precede your query by this citation? What do you have to say here about the syntax proposed by Jn Fairbarn, or whatever??) I am Haskell USER. I have no ambition to save the world. The "proposal" has been presented in 1995 in Nijmegen (FP in education). Actually, it hasn't, I concentrated on lazy power series etc., and the math oriented prelude has been mentioned casually. Jeroen Fokker presented similar ideas, implemented differently. If you have nothing else to do (but only in this case!) you may find the modified prelude called math.hs for Hugs (which needs a modified prelude.hs exporting primitives) in http://users.info.unicaen.fr/~karczma/humat/ This is NOT a "public proposal" and I *don't want* your public comments on it. If you want to be nice, show me some of *your* Haskell programs. Jerzy Karczmarczuk Caen, France ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Deja vu: Re: In hoc signo vinces (Was: Revamping the numeric classes)
[incomprehensible (not necessarily wrong!) stuff about polynomials, rings, modules over Z and complaints about the current prelude nuked] --- Marcin 'Qrczak' Kowalczyk pisze --- Please show a concrete proposal how Prelude classes could be improved. --- Jerzy Karczmarczuk repondre --- I am Haskell USER. I have no ambition to save the world. The "proposal" has been presented in 1995 in Nijmegen (FP in education). Actually, it hasn't, I concentrated on lazy power series etc., and the math oriented prelude has been mentioned casually. Jeroen Fokker presented similar ideas, implemented differently. I'm afraid all this discussion reminds me the one we had a year or two ago. At that time the mathematically inclined side was lead by Sergei, who to his credit developed the Basic Algebra Proposal, which I don't understand, but many people seemed to be happy about at that time. And then of course nothing happend, because no haskell implementor has bitten the bullet and implemented the proposal. This is something understandable as supporting Sergei's proposal seem to be a lot of work, most of which would be incompatible with current implementations. And noone wants to maintain *two* haskell compilers within one. Even if this discussion continues and another brave soul develops another algebra proposal I am prepared to bet with both of you in one years supply of Ben and Jerry's (not Jerzy :)!) icecream that nothing will continue to happen on the implementors side. It is simply too much work for an *untested* (in practice, for teaching etc) alternative prelude. So instead of wasting time, why don't you guys ask the implementors to provide a flag '-IDontWantYourStinkingPrelude' which would give you a bare metal compiler with no predefined types, functions, classes, no derived instances, no fancy stuff and build and test your proposals with it? I guess the RULES pragma (in GHC) could be abused to allow access to the primitive operations (on Ints), but you are still likely to loose much of the elegance, conciseness and perhaps even some efficiency of Haskell (e.g. list comprehensions), but this should allow us to gain experience in what sort of support is essential for providing alternative prelude(s). Once we learnt how to decouple the prelude from the compiler, and gained experience with alternative preludes implementors would have no excuse not to provide the possibility (unless it turns out to be completely impossible or impractical, in which case we learnt something genuinely useful). So, Marcin (as you are one of the GHC implementors), how much work would it be do disable the disputed Prelude stuff within the compiler, and what would be lost? Laszlo [Disclaimer: Just my 10 wons. This message is not in disagreement or agreement with any of the previous messages] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Sun, 11 Feb 2001 13:37:28 +1300, Brian Boutel [EMAIL PROTECTED] pisze: Can you demonstrate a revised hierarchy without Eq? What would happen to Ord and the numeric classes with default class method definitions that use (==) either explicitly or in pattern matching against numeric literals? OK, then you can't write these default method definitions. I'm against removing Eq from the numeric hierarchy, against making Num instances for functions, but I would probably remove Show. I haven't seen a sensible proposal of a replacement of the whole hierarchy. In an instance declaration, if a method requires operations of another class which is not a superclass of the class being instanced, it is sufficient to place the requirement in the context, Better: it is sufficient if the right instance is defined somewhere. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Sun, 11 Feb 2001 13:37:28 +1300, Brian Boutel [EMAIL PROTECTED] pisze: Can you demonstrate a revised hierarchy without Eq? What would happen to Ord and the numeric classes with default class method definitions that use (==) either explicitly or in pattern matching against numeric literals? I anticipate that some restructuring of the numeric classes must be done in order to accomplish this. I am, of course, attempting to contrive such a beast for my own personal use. On Sun, Feb 11, 2001 at 07:59:38AM +, Marcin 'Qrczak' Kowalczyk wrote: OK, then you can't write these default method definitions. I'm against removing Eq from the numeric hierarchy, against making Num instances for functions, but I would probably remove Show. I haven't seen a sensible proposal of a replacement of the whole hierarchy. Well, there are a couple of problems with someone like myself trying to make such a proposal. First, I'm a bit too marginalized and/or committed to a radical alternative. Second, I don't have the right associations or perhaps other resources. Removing Eq sounds like a good idea to me, in all honesty, though I think numeric instances for functions (at least by default) aren't great ideas. More details follow: Regarding Eq, there are other types besides functions which might not be good ideas to define equality on, either because they're not efficiently implementable or are still inappropriate. Matrix types aren't good candidates for defining equality, for one. Another one you might not want to define equality on are formal power series represented by infinite lists, since equality tests will never terminate. A third counterexample comes, of course, from graphics, where one might want to conveniently scale and translate solids. Testing meshes and surface representations for equality is once again not a great idea. Perhaps these counterexamples are a little contrived, but perhaps other people can come up with better ones. As far as the function instances of numeric types, there are some nasty properties that they have that probably make it a bad idea. In particular, I discovered that numeric literals' fromInteger property creates the possibility that something which is supposed to be a scalar or some other numeric result might accidentally be applied. For instance, given an expression with an intermediate numeric result like: f u v . g x y $ h z which is expected to produce a number, one could accidentally apply a numeric literal or something bound to one to some arguments, creating a bug. So this is for at least partial agreement, though I think it should be available in controlled circumstances. Local module importations and/or scoped instances might help here, or perhaps separating out code that relies upon them into a module where the instance is in scope, as it probably needs control which is that tight. Sun, 11 Feb 2001 13:37:28 +1300, Brian Boutel [EMAIL PROTECTED] pisze: In an instance declaration, if a method requires operations of another class which is not a superclass of the class being instanced, it is sufficient to place the requirement in the context, On Sun, Feb 11, 2001 at 07:59:38AM +, Marcin 'Qrczak' Kowalczyk wrote: Better: it is sufficient if the right instance is defined somewhere. Again, I'd be careful with this idea. It's poor design to unnecessarily restrict the generality of code. Of course, it's poor design to not try to enforce necessary conditions in the type system, too, which is why library design is nontrivial. And, of course, keeping it simple enough for use by the general populace (or whatever semblance thereof exists within the Haskell community) might well conflict with the desires of persons like myself who could easily fall prey to the accusation that they're trying to turn Haskell into a computer algebra system, and adds yet another constraint to the library design making it even tougher. Cheers, Bill ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Marcin 'Qrczak' Kowalczyk wrote: I'm against removing Eq from the numeric hierarchy, against making Num instances for functions, but I would probably remove Show. I haven't seen a sensible proposal of a replacement of the whole hierarchy. Then we probably are in agreement. --brian ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
On 11-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: There may be some misunderstanding here. If you are talking about type for which equality is always undefined, then I agree with you, but that is not what I was talking about. I was thinking about types where equality is defined for some pairs of argument values and undefined for others - I think the original example was some kind of arbitrary precision reals. On Sun, Feb 11, 2001 at 06:24:33PM +1100, Fergus Henderson wrote: The original example was treating functions as a numeric type. In the case of functions, computing equality is almost always infeasible. But you can easily define addition etc. pointwise: f + g = (\ x - f x + g x) I have a fairly complete implementation of this with dummy instances of Eq and Show for those who want to see the consequences of this. I found, interestingly enough, that any type constructor f with the following three properties could have an instance of Num defined upon f a: (1) it has a unary constructor to lift scalars (2) it has a Functor instance (3) it has an analogue of zip which can be defined upon it or, more precisely: \begin{code} instance (Eq (f a), Show (f a), Num a, Functor f, Zippable f, HasUnaryCon f) = Num (f a) where f + g = fmap (uncurry (+)) $ fzip f g f * g = fmap (uncurry (*)) $ fzip f g f - g = fmap (uncurry (-)) $ fzip f g negate = fmap negate abs = fmap abs signum = fmap signum fromInteger = unaryCon . fromInteger class Zippable f where fzip :: f a - f b - f (a,b) class HasUnaryCon f where unaryCon :: a - f a instance Functor ((-) a) where fmap = (.) instance Zippable ((-) a) where fzip f g = \x - (f x, g x) instance HasUnaryCon ((-) a) where unaryCon = const \end{code} and this generalizes nicely to other data types: \begin{code} instance Zippable Maybe where fzip (Just x) (Just y) = Just (x,y) fzip _ Nothing = Nothing fzip Nothing _ = Nothing instance HasUnaryCon Maybe where unaryCon = Just instance Zippable [ ] where fzip = zip instance HasUnaryCon [ ] where unaryCon = cycle . (:[]) \end{code} On 11-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: Returning to the basic issue, I understood the desire to remove Eq as a superclass of Num was so that people were not required to implement equality if they did not need it, not that there were significant numbers of useful numeric types for which equality was not meaningful. On Sun, Feb 11, 2001 at 06:24:33PM +1100, Fergus Henderson wrote: The argument is the latter, with functions as the canonical example. Well, usually equality as a mathematical concept is meaningful, but either not effectively or efficiently computable. Given an enumerable and bounded domain, equality may be defined (perhaps inefficiently) on functions by \begin{code} instance (Enum a, Bounded a, Eq b) = Eq (a-b) where f == g = all (uncurry (==)) $ zipWith (\x - (f x, g x)) [minBound..maxBound] \end{code} and as I've said in another post, equality instances on data structures expected to be infinite, very large, or where the semantics of equality are make it difficult to compute, or perhaps even cases where it's just not useful are also not good to be forced. Cheers, Bill ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Marcin 'Qrczak' Kowalczyk writes: | Fri, 9 Feb 2001 17:29:09 +1300, Tom Pledger [EMAIL PROTECTED] pisze: | | (x + y) + z | | we know from the explicit type signature (in your question that I was | responding to) that x,y::Int and z::Double. Type inference does not | need to treat x or y up, because it can take the first (+) to be Int | addition. However, it must treat the result (x + y) up to the most | specific supertype which can be added to a Double. | | Approach it differently. z is Double, (x+y) is added to it, so | (x+y) must have type Double. That's a restriction I'd like to avoid. Instead: ...so the most specific common supertype of Double and (x+y)'s type must support addition. | This means that x and y must have type Double. This is OK, because | they are Ints now, which can be converted to Double. | | Why is your approach better than mine? It used a definition of (+) which was a closer fit for the types of x and y. : | h:: (Subtype a b, Subtype Int b, Eq b) = (Int - a) - Bool | | This type is ambiguous: the type variable b is needed in the | context but not present in the type itself, so it can never be | determined from the usage of h. Yes, I rashly glossed over the importance of having well-defined most specific common supertype (MSCS) and least specific common subtype (LSCS) operators in a subtype lattice. Here's a more respectable version: h :: Eq (MSCS a Int) = (Int - a) - Bool | That can be inferred by following the structure of the term. | Function terms do seem prone to an accumulation of deferred | subtype constraints. | | When function application generates a constraint, the language gets | ambiguous as hell. Applications are found everywhere through the | program! Very often the type of the argument or result of an | internal application does not appear in the type of the whole | function being defined, which makes it ambiguous. | | Not to mention that there would be *LOTS* of these constraints. | Application is used everywhere. It's important to have its typing | rule simple and cheap. Generating a constraint for every | application is not an option. These constraints tend to get discharged whenever the result of an application is not another function. The hellish ambiguities can be substantially tamed by insisting on a properly constructed subtype lattice. Anyway, since neither of us is about to have a change of mind, and nobody else is showing an interest in this branch of the discussion, it appears that the most constructive thing for me to do is return to try-to-keep-quiet-about-subtyping-until-I've-done-it-in-THIH mode. Regards, Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Marcin 'Qrczak' Kowalczyk wrote: Sat, 10 Feb 2001 14:09:59 +1300, Brian Boutel [EMAIL PROTECTED] pisze: Can you demonstrate a revised hierarchy without Eq? What would happen to Ord, and the numeric classes that require Eq because they need signum? signum doesn't require Eq. You can use signum without having Eq, and you can sometimes define signum without having Eq (e.g. on functions). Sometimes you do require (==) to define signum, but it has nothing to do with superclasses. Let me restate my question more carefully: Can you demonstrate a revised hierarchy without Eq? What would happen to Ord and the numeric classes with default class method definitions that use (==) either explicitly or in pattern matching against numeric literals? Both Integral and RealFrac do this to compare or test the value of signum. In an instance declaration, if a method requires operations of another class which is not a superclass of the class being instanced, it is sufficient to place the requirement in the context, but for default class method definitions, all class methods used must belong to the class being defined or its superclasses. --brian ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Fergus Henderson wrote: On 09-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: Patrik Jansson wrote: The fact that equality can be trivially defined as bottom does not imply that it should be a superclass of Num, it only explains that there is an ugly way of working around the problem. ... There is nothing trivial or ugly about a definition that reflects reality and bottoms only where equality is undefined. I disagree. Haskell is a statically typed language, and having errors which could easily be detected at compile instead being deferred to run time is ugly in a statically typed language. There may be some misunderstanding here. If you are talking about type for which equality is always undefined, then I agree with you, but that is not what I was talking about. I was thinking about types where equality is defined for some pairs of argument values and undefined for others - I think the original example was some kind of arbitrary precision reals. My remark about "a definition that reflects reality and bottoms only where equality is undefined" was referring to this situation. Returning to the basic issue, I understood the desire to remove Eq as a superclass of Num was so that people were not required to implement equality if they did not need it, not that there were significant numbers of useful numeric types for which equality was not meaningful. Whichever of these was meant, I feel strongly that accomodating this and other similar changes by weakening the constraints on what Num in Haskell implies, is going too far. It devalues the Class structure in Haskell to the point where its purpose, to control ad hoc polymorphism in a way that ensures that operators are overloaded only on closely related types, is lost, and one might as well abandon Classes and allow arbitrary overloading. --brian --brian ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
On 11-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: Fergus Henderson wrote: On 09-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: Patrik Jansson wrote: The fact that equality can be trivially defined as bottom does not imply that it should be a superclass of Num, it only explains that there is an ugly way of working around the problem. ... There is nothing trivial or ugly about a definition that reflects reality and bottoms only where equality is undefined. I disagree. Haskell is a statically typed language, and having errors which could easily be detected at compile instead being deferred to run time is ugly in a statically typed language. There may be some misunderstanding here. If you are talking about type for which equality is always undefined, then I agree with you, but that is not what I was talking about. I was thinking about types where equality is defined for some pairs of argument values and undefined for others - I think the original example was some kind of arbitrary precision reals. The original example was treating functions as a numeric type. In the case of functions, computing equality is almost always infeasible. But you can easily define addition etc. pointwise: f + g = (\ x - f x + g x) Returning to the basic issue, I understood the desire to remove Eq as a superclass of Num was so that people were not required to implement equality if they did not need it, not that there were significant numbers of useful numeric types for which equality was not meaningful. The argument is the latter, with functions as the canonical example. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit | of excellence is a lethal habit" WWW: http://www.cs.mu.oz.au/~fjh | -- the last words of T. S. Garp. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Brian Boutel [EMAIL PROTECTED] writes: The fact that equality can be trivially defined as bottom does not imply that it should be a superclass of Num, it only explains that there is an ugly way of working around the problem. There is nothing trivial or ugly about a definition that reflects reality and bottoms only where equality is undefined. I think there is. If I design a class and derive it from Num with (==) is bottom, I am allowed to apply to it functions requiring a Num argument, but I have no guarantee it will work. The implementor of that function can change its internals (to use (==)), and suddenly my previously working program is non-terminating. If I defined (==) to give a run time error, it'd be a bit better, but I'd much prefer the compiler to tell me about this in advance. Of course, if you do not need to apply equality to your "numeric" type then having to define it is a waste of time, but consider this: It's not about "needing to apply", but about finding a reasonable definition. - Having a class hierarchy at all (or making any design decision) implies compromise. I think the argument is that we should move Eq and Show *out* of the Num hierarchy. Less hierarchy - less compromise. - The current hierarchy (and its predecessors) represent a reasonable compromise that meets most needs. Obviously a lot of people seem to think we could find compromises that are more reasonable. - Users have a choice: either work within the class hierarchy and accept the pain of having to define things you don't need in order to get the things that come for free, Isn't it a good idea to reduce the amount of pain? or omit the instance declarations and work outside the hierarchy. In that case you will not be able to use the overloaded operator symbols of the class, but that is just a matter of concrete syntax, and ultimately unimportant. I don't think syntax is unimportant. -kzm -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
In hoc signo vinces (Was: Revamping the numeric classes)
Marcin 'Qrczak' Kowalczyk wrote: JK Now, signum and abs seem to be quite distincts beasts. Signum seem JK to require Ord (and a generic zero...). Signum doesn't require Ord. signum z = z / abs z for complex numbers. Thank you, I know. And I ignore it. Calling "signum" the result of a vector normalization (on the gauss plane in this case) is something I don't really appreciate, and I wonder why this definition infiltrated the prelude. Just because it conforms to the "normal" definition of signum for reals? Again, a violation of the orthogonality principle. Needing division just to define signum. And of course a completely different approach do define the signum of integers. Or of polynomials... Jerzy Karczmarczuk ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: In hoc signo vinces (Was: Revamping the numeric classes)
Fri, 09 Feb 2001 10:52:39 +, Jerzy Karczmarczuk pisze: Again, a violation of the orthogonality principle. Needing division just to define signum. And of course a completely different approach do define the signum of integers. Or of polynomials... On Fri, Feb 09, 2001 at 07:19:21PM +, Marcin 'Qrczak' Kowalczyk wrote: So what? That's why it's a class method and not a plain function with a single definition. Multiplication of matrices is implemented differently than multiplication of integers. Why don't you call it a violation of the orthogonality principle (whatever it is)? Matrix rings actually manage to expose the inappropriateness of signum and abs' definitions and relationships to Num very well: class (Eq a, Show a) = Num a where (+), (-), (*) :: a - a - a negate :: a - a abs, signum :: a - a fromInteger :: Integer - a fromInt :: Int - a -- partain: Glasgow extension Pure arithmetic ((+), (-), (*), negate) works just fine. But there are no good injections to use for fromInteger or fromInt, the type of abs is wrong if it's going to be a norm, and it's not clear that signum makes much sense. So we have two totally inappropriate operations (fromInteger and fromInt), one operation which has the wrong type (abs), and an operation which doesn't have well-defined meaning (signum) on matrices. If we want people doing graphics or linear algebraic computations to be able to go about their business with their code looking like ordinary arithmetic, this is, perhaps, a real concern. I believe that these applications are widespread enough to be concerned about how the library design affects their aesthetics. Cheers, Bill -- craving Weak coffee is only fit for lemmas. -- ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Ketil Malde wrote: Brian Boutel [EMAIL PROTECTED] writes: - Having a class hierarchy at all (or making any design decision) implies compromise. I think the argument is that we should move Eq and Show *out* of the Num hierarchy. Less hierarchy - less compromise. Can you demonstrate a revised hierarchy without Eq? What would happen to Ord, and the numeric classes that require Eq because they need signum? - The current hierarchy (and its predecessors) represent a reasonable compromise that meets most needs. Obviously a lot of people seem to think we could find compromises that are more reasonable. I would put this differently. "A particular group of people want to change the language to make it more convenient for their special interests." - Users have a choice: either work within the class hierarchy and accept the pain of having to define things you don't need in order to get the things that come for free, Isn't it a good idea to reduce the amount of pain? Not always. or omit the instance declarations and work outside the hierarchy. In that case you will not be able to use the overloaded operator symbols of the class, but that is just a matter of concrete syntax, and ultimately unimportant. I don't think syntax is unimportant. I wrote that *concrete* syntax is ultimately unimportant, not *syntax*. There is a big difference. In particular, *lexical syntax*, the choice of marks on paper used to represent a language element, is not important, although it does give rise to arguments, as do all mattters of taste and style. Thre are not enough usable operator symbols to go round, so they get overloaded. Mathematicians have overloaded common symbols like (+) and (*) for concepts that have may some affinity with addition and multiplication in arithmetic, but which are actually quite different. That's fine, because, in context, expert human readers can distinguish what is meant. From a software engineering point of view, though, such free overloading is dangerous, because readers may assume, incorrectly, that an operator has properties that are typically associated with operators using that symbol. This may not matter in a private world where the program writer is the only person who will see and use the code, and no mission-critial decisions depend on the results, but it should not be the fate of Haskell to be confined to such use. Haskell could have allowed free ad hoc overloading, but one of the first major decisions made by the Haskell Committee in 1988 was not to do so. Instead, it adopted John Hughes' proposal to introduce type classes to control overloading. A symbol could only be overloaded if the whole of a group of related symbols (the Class) was overloaded with it, and the class hierarchy provided an even stronger constraint by restricting overloading of the class operators to cases where other classes, intended to be closely related, were also overloaded. This tended to ensure that the new type at which the classes were overloaded had strong resemblences to the standard types. Simplifying the hierarchy weakens these constraints and so should be approached with extreme caution. Of course, the details of the classes and the hierarchy have changed over the years - there is, always has been and always will be pressure to make changes to meet particular needs - but the essence is still there, and the essence is of a general-purpose language, not a domain-specific language for some branches of mathematics. A consequence of this is that certain uses of overloaded symbols are inconvenient, because they are too far from the mainstream intended meaning. If you have such a use, and you want to write in Haskell, you have to choose other lexical symbols to represent your operators. You make your choice. --brian ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
On 08-Feb-2001, Marcin 'Qrczak' Kowalczyk [EMAIL PROTECTED] wrote: I don't like the idea of treating the case "no explicit definitions were given because all have default definitions which are OK" differently than "some explicit definitions were given". I don't really like it that much either, but... When there is a superclass, it must have an instance defined, so if we permit such thing at all, I would let it implicitly define all superclass instances not defined explicitly, or something like that. At least when all methods have default definitions. Yes, I know that they can be mutually recursive and thus all will be bottoms... ... that is the problem I was trying to solve. So maybe there should be a way to specify that default definitions are cyclic and some of them must be defined? I agree 100%. It is usually written in comments anyway, because it is not immediately visible in the definitions. Yes. Much better to make it part of the language, so that the compiler can check it. (now any method definition can be omitted even if it has no default!), Yeah, that one really sucks. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit | of excellence is a lethal habit" WWW: http://www.cs.mu.oz.au/~fjh | -- the last words of T. S. Garp. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
On 09-Feb-2001, Brian Boutel [EMAIL PROTECTED] wrote: Patrik Jansson wrote: The fact that equality can be trivially defined as bottom does not imply that it should be a superclass of Num, it only explains that there is an ugly way of working around the problem. ... There is nothing trivial or ugly about a definition that reflects reality and bottoms only where equality is undefined. I disagree. Haskell is a statically typed language, and having errors which could easily be detected at compile instead being deferred to run time is ugly in a statically typed language. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit | of excellence is a lethal habit" WWW: http://www.cs.mu.oz.au/~fjh | -- the last words of T. S. Garp. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
Sat, 10 Feb 2001 14:09:59 +1300, Brian Boutel [EMAIL PROTECTED] pisze: Can you demonstrate a revised hierarchy without Eq? What would happen to Ord, and the numeric classes that require Eq because they need signum? signum doesn't require Eq. You can use signum without having Eq, and you can sometimes define signum without having Eq (e.g. on functions). Sometimes you do require (==) to define signum, but it has nothing to do with superclasses. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
On Thu, 8 Feb 2001, Tom Pledger wrote: nice answer: give the numeric literal 10 the range type 10..10, which is defined implicitly and is a subtype of both -128..127 (Int8) and 0..255 (Word8). What are the inferred types for f = map (\x - x+10) g l = l ++ f l ? I hope I can use them as [Int] - [Int]. x + y + z -- as above -- (x + y) + z -- left-associativity of (+) -- realToFrac (x + y) + z-- injection (or treating up) done -- conservatively, i.e. only where needed What does it mean "where needed"? Type inference does not proceed inside-out. What about this? h f = f (1::Int) == (2::Int) Can I apply f to a function of type Int-Double? If no, then it's a pity, because I could inline it (the comparison would be done on Doubles). If yes, then what is the inferred type for h? Note that Int-Double is not a subtype of Int-Int, so if h :: (Int-Int)-Bool, then I can't imagine how h can be applied to something :: Int-Double. -- Marcin 'Qrczak' Kowalczyk ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
First, a general remark which has nothing to do with Num. PLEASE WATCH YOUR DESTINATION ADDRESSES People send regularly their postings to haskell-cafe with several private receiver addresses, which is a bit annoying when you click "reply all"... Brian Boutel after Dylan Thurston: Why doesn't your argument show that all types should by instances of Eq and Show? Why are numeric types special? Why do you think it does? I certainly don't think so. The point about Eq was that a objection was raised to Num being a subclass of Eq because, for some numeric types, equality is undecidable. I suggested that Haskell equality could be undecidable, so (==) on those types could reflect the real situation. One would expect that it could do so in a natural way, producing a value of True or False when possible, and diverging otherwise. Thus no convincing argument has been given for removing Eq as a superclass of Num. In general, if you fine-grain the Class heirarchy too much, the picture gets very complicated. If you need to define separate subclases of Num for those types which have both Eq and Show, those that only Have Eq, those than only have Show and those that have neither, not to mention those that have Ord as well as Eq and those that don't, and then for all the other distinctions that will be suggested, my guess is that Haskell will become the preserve of a few mathematicians and everyone else will give up in disgust. Then the likely result is that no-one will be interested in maintaining and developing Haskell and it will die. Strange, but from the objectives mentioned in the last part of this posting (even if a little demagogic [insert smiley here if you wish]) I draw opposite conclusions. The fact that the number of cases is quite large suggests that Eq, Show and arithmetic should be treated as *orthogonal* issues, and treated independently. If somebody needs Show for his favourite data type, he is free to arrange this himself. I repeat what I have already said: I work with functional objects as mathematical entities. I want to add parametric surfaces, to rotate trajectories. Also, to handle gracefully and legibly for those simpletons who call themselves 'theoretical physicists', the arithmetic of un-truncated lazy streams representing power series, or infinitely dimensional differential algebra elements. Perhaps those are not convincing arguments for Brian Boutel. They are certainly so for me. Num, with this forced marriage of (+) and (*) violates the principle of orthogonality. Eq and Show constraints make it worse. === And, last, but very high on my check-list: The implicit coercion of numeric constants: 3.14 -=- (fromDouble 3.14) etc. is sick. (Or was; I still didn't install the last version of GHC, and with Hugs it is bad). The decision is taken by the compiler internally, and it doesn't care at all about the fact that in my prelude I have eliminated the Num class and redefined fromDouble, fromInt, etc. + Dylan Thurston terminates his previous posting about Num with: Footnotes: [1] Except for the lack of abs and signum, which should be in some other class. I have to think about their semantics before I can say where they belong. Now, signum and abs seem to be quite distincts beasts. Signum seem to require Ord (and a generic zero...). Abs from the mathematical point of view constitutes a *norm*. Now, frankly, I haven't the slightest idea how to cast this concept into Haskell class hierarchy in a sufficiently general way... I'll tell you anyway that if you try to "sanitize" the numeric classes, if you separate additive structures and the multiplication, if you finally define abstract Vectors over some field of scalars, and if you demand the existence of a generic normalization for your vectors, than *most probably* you will need multiparametric classes with dependencies. Jerzy Karczmarczuk Caen, France ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
On Thu, Feb 08, 2001 at 11:24:49AM +, Jerzy Karczmarczuk wrote: First, a general remark which has nothing to do with Num. PLEASE WATCH YOUR DESTINATION ADDRESSES People send regularly their postings to haskell-cafe with several private receiver addresses, which is a bit annoying when you click "reply all"... Yes, apologies. The way the lists do the headers make it very easy to reply to individuals, and hard to reply to the list. And, last, but very high on my check-list: The implicit coercion of numeric constants: 3.14 -=- (fromDouble 3.14) etc. is sick. (Or was; I still didn't install the last version of GHC, and with Hugs it is bad). The decision is taken by the compiler internally, and it doesn't care at all about the fact that in my prelude I have eliminated the Num class and redefined fromDouble, fromInt, etc. Can't you just put "default ()" at the top of each module? I suppose you still have the problem that a numeric literal "5" means "Prelude.fromInteger 5". Can't you define your types to be instances of Prelude.Num, with no operations defined except Prelude.fromInteger? Dylan Thurston terminates his previous posting about Num with: Footnotes: [1] Except for the lack of abs and signum, which should be in some other class. I have to think about their semantics before I can say where they belong. Now, signum and abs seem to be quite distincts beasts. Signum seem to require Ord (and a generic zero...). Abs from the mathematical point of view constitutes a *norm*. Now, frankly, I haven't the slightest idea how to cast this concept into Haskell class hierarchy in a sufficiently general way... This was one thing I liked with the Haskell hierarchy: the observation that "signum" of real numbers is very much like "argument" of complex numbers. abs and signum in Haskell satisfy an implicit law: abs x * signum x = x [1] So signum can be defined anywhere you can define abs (except that it's not a continuous function, so is not terribly well-defined). A default definition for signum x might read signum x = let a = abs x in if (a == 0) then 0 else x / abs x (Possibly signum is the wrong name. What is the standard name for this operation for, e.g., matrices?) [Er, on second thoughts, it's not as well-defined as I thought. Abs x needs to be in a field for the definition above to work.] I'll tell you anyway that if you try to "sanitize" the numeric classes, if you separate additive structures and the multiplication, if you finally define abstract Vectors over some field of scalars, and if you demand the existence of a generic normalization for your vectors, than *most probably* you will need multiparametric classes with dependencies. Multiparametric classes, certainly (for Vectors, at least). Fortunately, they will be in Haskell 2 with high probability. I'm not convinced about dependencies yet. Jerzy Karczmarczuk Caen, France Best, Dylan Thurston Footnotes: [1] I'm not sure what I mean by "=" there, since I do not believe these should be forced to be instances of Eq. For clearer cases, consider the various Monad laws, e.g., join . join = join . map join (Hope I got that right.) What does "=" mean there? Some sort of denotational equality, I suppose. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Thu, 8 Feb 2001 10:51:58 -0500, Peter Douglass [EMAIL PROTECTED] pisze: The first part of my question (not contained in your reply) is whether it is feasible to disable a developer's access to the "unsafe" numerical operations. import Prelude hiding (quot, rem, (/) {- etc. -}) import YourPrelude -- which defines substitutes You can "disable" it now. You cannot disable them entirely - anyone can define present functions in terms of your functions if he really wants. Whether or not an individual developer chooses to do so is another matter. Why only quot? There are many other ways to write bottom: head [] (\(x:xs) - (x,xs)) [] let x = x in x log (-1) asin 2 error "foo" If you "know" the value is non-zero before run-time, then that is statically determined. I know but the compiler does not know, and I have no way to convince it. It is possible that the developer writes a function which returns a nonZeroNumeric value which actually has a value of zero. However, the value of requiring division to have a nonZeroNumeric denominator is to catch at compile time the "error" of failing to scrutinize (correctly or incorrectly) for zero. IMHO it would be more painful than useful. For most commercial software, the quality of run-time error messages is far less important than their absence. It would not avoid them if the interface does not give a place to report the error: average xs = sum xs / case checkZero (length xs) of Just notZero - notZero Nothing - error "This should never happen" is not any more safe than average xs = sum xs / length xs and I can report bad input without trouble now: average xs = case length xs of 0 - Nothing l - Just (sum xs / l) -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Thu, 8 Feb 2001 21:41:56 +1100, Fergus Henderson [EMAIL PROTECTED] pisze: Should this define an instance for `foo T'? (I think not.) How about if the instance declaration is changed to instance bar T where f = 41 -- no definition for f2 b = 42 ? (In that case, I think it should.) I don't like the idea of treating the case "no explicit definitions were given because all have default definitions which are OK" differently than "some explicit definitions were given". When there is a superclass, it must have an instance defined, so if we permit such thing at all, I would let it implicitly define all superclass instances not defined explicitly, or something like that. At least when all methods have default definitions. Yes, I know that they can be mutually recursive and thus all will be bottoms... So maybe there should be a way to specify that default definitions are cyclic and some of them must be defined? It is usually written in comments anyway, because it is not immediately visible in the definitions. If not formally in the language (now any method definition can be omitted even if it has no default!), then perhaps the compiler could detect most cases when methods are defined in terms of one another and give a warning. Generally the compiler could warn if the programmer has written bottom in an unusual way. For example f x = g some_expression g x = f some_expression is almost certainly a programmer error. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Thu, 08 Feb 2001 11:24:49 +, Jerzy Karczmarczuk [EMAIL PROTECTED] pisze: The implicit coercion of numeric constants: 3.14 -=- (fromDouble 3.14) etc. is sick. What do you propose instead? (BTW, it's fromRational, to keep arbitrarily large precision.) Now, signum and abs seem to be quite distincts beasts. Signum seem to require Ord (and a generic zero...). Signum doesn't require Ord. signum z = z / abs z for complex numbers. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
On Thu, Feb 08, 2001 at 08:30:31PM +, Marcin 'Qrczak' Kowalczyk wrote: Signum doesn't require Ord. signum z = z / abs z for complex numbers. I'd be careful here. \begin{code} signum 0 = 0 signum z = z / abs z \end{code} This is, perhaps, neither precise nor general enough. The signum/abs pair seem to represent direction and magnitude. According to the line of reasoning in some of the earlier posts in this flamewar, the following constraints: (1) z = signum z * abs z where * is appropriately defined (2) abs $ signum z = 1 should be enforced, if possible, by the type system. This suggests that for any type having a vector space structure over Fractional (or whatever the hierarchy you're brewing up uses for rings with a division partial function on them) that the result type of signum lives in a more restricted universe, perhaps even one with a different structure (operations defined on it, set of elements) than the argument type, and it seems more than possible to parametrize it on the argument type. The abs is in fact a norm, and the signum projects V^n - V^n / V. Attempts to define these things on Gaussian integers, p-adic numbers, polynomial rings, and rational points on elliptic curves will quickly reveal limitations of the stock class hierarchy. Now, whether it's actually desirable to scare newcomers to the language into math phobia, wetting their pants, and running screaming with subtleties like this suggests perhaps that one or more "alternative Preludes" may be desirable to have. There is a standard Prelude, why not a nonstandard one or two? We have the source. The needs of the geek do not outweigh the needs of the many. Hence, we can cook up a few Preludes or so on our own, and certainly if we can tinker enough to spam the list with counterexamples and suggestions of what we'd like the Prelude to have, we can compile up a Prelude for ourselves with our "suggested changes" included and perhaps one day knock together something which can actually be used and has been tested, no? The Standard Prelude serves its purpose well and accommodates the largest cross-section of users. Perhaps a Geek Prelude could accommodate the few of us who do need these sorts of schenanigans. Cheers, Bill -- j0][nD33R:#math Excel/Spreadsheet Q: What is the formula for finding out the time passed between two dates and or two times in the same day? MatroiDN:#math excel/spreadsheet? Hmm, this is math? Is there a GTM on excel or maybe an article in annals about spreadsheets or maybe there's a link from wolfram to doing your own computer work, eh? danprime:#math jeeem, haven't you seen "Introduction to Algebraic Excel"? danprime:#math or "Spreadsheet Space Embeddings in 2-Manifolds" brouwer:#math i got my phd in spreadsheet theory brouwer:#math i did my thesis on the spreadsheet conjecture ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Marcin 'Qrczak' Kowalczyk writes: | On Thu, 8 Feb 2001, Tom Pledger wrote: | | nice answer: give the numeric literal 10 the range type 10..10, which | is defined implicitly and is a subtype of both -128..127 (Int8) and | 0..255 (Word8). | | What are the inferred types for | f = map (\x - x+10) | g l = l ++ f l | ? I hope I can use them as [Int] - [Int]. f, g :: (Subtype a b, Subtype 10..10 b, Num b) = [a] - [b] Yes, because of the substitution {Int/a, Int/b}. | x + y + z -- as above | | -- (x + y) + z -- left-associativity of (+) | | -- realToFrac (x + y) + z-- injection (or treating up) done |-- conservatively, i.e. only where needed | | What does it mean "where needed"? Type inference does not proceed | inside-out. In the expression (x + y) + z we know from the explicit type signature (in your question that I was responding to) that x,y::Int and z::Double. Type inference does not need to treat x or y up, because it can take the first (+) to be Int addition. However, it must treat the result (x + y) up to the most specific supertype which can be added to a Double. | What about this? | h f = f (1::Int) == (2::Int) | Can I apply f h? | to a function of type Int-Double? Yes. | If no, then it's a pity, because I could inline it (the comparison | would be done on Doubles). If yes, then what is the inferred type | for h? Note that Int-Double is not a subtype of Int-Int, so if h | :: (Int-Int)-Bool, then I can't imagine how h can be applied to | something :: Int-Double. There's no explicit type signature for the result of applying f to (1::Int), so... h :: (Subtype a b, Subtype Int b, Eq b) = (Int - a) - Bool That can be inferred by following the structure of the term. Function terms do seem prone to an accumulation of deferred subtype constraints. Regards, Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
William Lee Irwin III wrote: The Standard Prelude serves its purpose well and accommodates the largest cross-section of users. Perhaps a Geek Prelude could accommodate the few of us who do need these sorts of schenanigans. Amen. --brian ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
moved to haskell-cafe Ketil E.g. way back, I wrote a simple differential equation solver. Ketil Now, the same function *could* have been applied to vector Ketil functions, except that I'd have to decide on how to implement Ketil all the "Num" stuff that really didn't fit well. Ideally, a Ketil nice class design would infer, or at least allow me to Ketil specify, the mathematical constraints inherent in an Ketil algorithm, and let my implementation work with any data Ketil satisfying those constraints. the problem is that the --majority, I suppose?-- of mathematicians tend to overload operators. They use "*" for matrix-matrix multiplication as well as for matrix-vector multiplication etc. Therefore, a quick solution that implements groups, monoids, Abelian groups, rings, Euclidean rings, fields, etc. will not be sufficient. I don't think that it is acceptable for a language like Haskell to permit the user to overload predefined operators, like "*". A cheap solution could be to define a type MathObject and operators like :*: MathObject - MathObject - MathObject Then, the user can implement: a :*: b = case (a,b) of (Matrix x, Matrix y) - foo (Matrix x, Vector y) - bar -- Christoph Herrmann E-mail: [EMAIL PROTECTED] WWW: http://brahms.fmi.uni-passau.de/cl/staff/herrmann.html ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Show, Eq not necessary for Num [Was: Revamping the numeric classes]
"Ch. A. Herrmann" answers my questions: Jerzy What do you mean "predefined" operators? Predefined where? In hugs, ":t (*)" tells you: (*) :: Num a = a - a - a which is an intended property of Haskell, I suppose. Aha. But I would never call this a DEFINITION of this operator. This is just the type, isn't it? A misunderstanding, I presume. Jerzy Forbid what? A definition like (a trivial example, instead of matrix/vector) class NewClass a where (*) :: a-[a]-a leads to an error OK, OK. Actually my only point was to suggest that the type for (*) as above should be constrained oinly by an *appropriate class*, not by this horrible Num which contains additive operators as well. So this is not the answer I expected, concerning the "overloading of a predefined operator". BTW. In Clean (*) constitutes a class by itself, that is this simplicity I appreciate, although I am far from saying that they have an ideal type system for a working mathemaniac. ... Also, the programming language should not prescribe that the "standard" mathematics is the right mathematics and the only the user is allowed to deal with. If the user likes to multiply two strings, like "ten" * "six" (= "sixty"), and he/she has a semantics for that, why not? Aaa, here we might, although need not disagree. I would like to see some rational constraints, preventing the user from inventing a completely insane semantics for this multiplication, mainly to discourage writing of programs impossible to understand. Jerzy Karczmarczuk Caen, France ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
07 Feb 2001 11:47:11 +0100, Ketil Malde [EMAIL PROTECTED] pisze: If it is useful to have a fine granularity of classes, you can imagine doing: class Multiplicative a b c where (*) :: a - b - c Then a*b*c is ambiguous no matter what are types of a,b,c and the result. Sorry, this does not work. Too general is too bad, it's impossible to have everything at once. -- __(" Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Other people have been making great points for me. (I particularly liked the example of Dollars as a type with addition but not multiplication.) One point that has not been made: given a class setup like class Additive a where (+) :: a - a - a (-) :: a - a - a negate :: a - a zero :: a class Multiplicative a where (*) :: a - a - a one :: a class (Additive a, Multiplicative a) = Num a where fromInteger :: Integer - a then naive users can continue to use (Num a) in contexts, and the same programs will continue to work.[1] (A question in the above context is whether the literal '0' should be interpreted as 'fromInteger (0::Integer)' or as 'zero'. Opinions?) On Wed, Feb 07, 2001 at 06:27:02PM +1300, Brian Boutel wrote: * Haskell equality is a defined operation, not a primitive, and may not be decidable. It does not always define equivalence classes, because a==a may be Bottom, so what's the problem? It would be a problem, though, to have to explain to a beginner why they can't print the result of a computation. Why doesn't your argument show that all types should by instances of Eq and Show? Why are numeric types special? Best, Dylan Thurston Footnotes: [1] Except for the lack of abs and signum, which should be in some other class. I have to think about their semantics before I can say where they belong. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
On Wed, Feb 07, 2001 at 11:47:11AM +0100, Ketil Malde wrote: "Ch. A. Herrmann" [EMAIL PROTECTED] writes: [...] the problem is that the --majority, I suppose?-- of mathematicians tend to overload operators. They use "*" for matrix-matrix multiplication as well as for matrix-vector multiplication etc. Yes, obviously. On the other hand, I think you could get far by defining (+) as an operator in a Group, (*) in a Ring, and so forth. As a complete newbie can I add a few points? They may be misguided, but they may also help identify what appears obvious only through use... - understanding the hierarchy of classes (ie constanly referring to Fig 5 in the report) takes a fair amount of effort. It would have been much clearer for me to have classes that simply listed the required super classes (as suggested in an earlier post). - even for me, no great mathematician, I found the forced inclusion of certain classes irritating (in my case - effectively implementing arithmetic on tuples - Enum made little sense and ordering is hacked in order to be total; why do I need to define either to overload "+"?) - what's the deal with fmap and map? Another problem is that the mathematical constructs include properties not easily encoded in Haskell, like commutativity, associativity, etc. I don't think that it is acceptable for a language like Haskell to permit the user to overload predefined operators, like "*". Do you mean that the numeric classes should be dropped or are you talking about some other overloading procedure? Isn't one popular use of Haskell to define/extend it to support small domain-specific languages? In those cases, overloading operatores via the class mechanism is very useful - you can give the user concise, but stll understandable, syntax for the problem domain. I can see that overloading operators is not good in general purpose libraries, unless carefully controlled, but that doesn't mean it is always bad, or should always be strictly controlled. Maybe the programmer could decide what is appropriate, faced with a particular problem, rather than a language designer, from more general considerations? Balance, as ever, is the key :-) [...] From experience, I guess there are probably issues that haven't crossed my mind. :-) This is certainly true in my case - I presumed there was some deep reason for the complex hierarchy that exists at the moment. It was a surprise to see it questioned here. Sorry if I've used the wrong terminology anywhere. Hope the above makes some sense. Andrew -- http://www.andrewcooke.free-online.co.uk/index.html - End forwarded message - -- http://www.andrewcooke.free-online.co.uk/index.html ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: Revamping the numeric classes
I have some questions about how Haskell's numeric classes might be revamped. Is it possible in Haskell to circumscribe the availability of certain "unsafe" numeric operations such as div, /, mod? If this is not possible already, could perhaps a compiler flag "-noUnsafeDivide" could be added to make such a restriction? What I have in mind is to remove division by zero as an untypable expression. The idea is to require div, /, mod to take NonZeroNumeric values in their second argument. NonZeroNumeric values could be created by functions of type: Number a = a - Maybe NonZeroNumeric or something similar. Has this been tried and failed? I'm curious as to what problems there might be with such an approach. --PeterD ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Revamping the numeric classes
Dylan Thurston writes: : | (A question in the above context is whether the literal '0' should | be interpreted as 'fromInteger (0::Integer)' or as 'zero'. | Opinions?) Opinions? Be careful what you wish for. ;-) In a similar discussion last year, I was making wistful noises about subtyping, and one of Marcin's questions http://www.mail-archive.com/haskell-cafe@haskell.org/msg00125.html was whether the numeric literal 10 should have type Int8 (2's complement octet) or Word8 (unsigned octet). At the time I couldn't give a wholly satisfactory answer. Since then I've read the oft-cited paper "On Understanding Types, Data Abstraction, and Polymorphism" (Cardelli Wegner, ACM Computing Surveys, Dec 1985), which suggests a nice answer: give the numeric literal 10 the range type 10..10, which is defined implicitly and is a subtype of both -128..127 (Int8) and 0..255 (Word8). The differences in arithmetic on certain important range types could be represented by multiple primitive functions (or perhaps foreign functions, through the FFI): primAdd :: Integer - Integer - Integer-- arbitrary precision primAdd8s :: Int8- Int8- Int8 -- overflow at -129, 128 primAdd8u :: Word8 - Word8 - Word8 -- overflow at -1, 256 -- etc. instance Additive Integer where zero = 0 (+) = primAdd ...with similar instances for the integer subrange types which may overflow. These other instances would belong outside the standard Prelude, so that the ambiguity questions don't trouble people (such as beginners) who don't care about the space and time advantages of fixed precision integers. Subtyping offers an alternative approach to handling arithmetic overflows: - Use only arbitrary precision arithmetic. - When calculated result *really* needs to be packed into a fixed precision format, project it (or treat it down, etc., whatever's your preferred name), so that overflows are represented as Nothing. For references to other uses of class Subtype see: http://www.mail-archive.com/haskell@haskell.org/msg07303.html For a reference to some unification-driven rewrites, see: http://www.mail-archive.com/haskell@haskell.org/msg07327.html Marcin 'Qrczak' Kowalczyk writes: : | Assuming that Ints can be implicitly converted to Doubles, is the | function | f :: Int - Int - Double - Double | f x y z = x + y + z | ambiguous? Because there are two interpretations: | f x y z = realToFrac x + realToFrac y + z | f x y z = realToFrac (x + y) + z | | Making this and similar case ambiguous means inserting lots of explicit | type signatures to disambiguate subexpressions. | | Again, arbitrarily choosing one of the alternatives basing on some | set of weighting rules is dangerous, I don't think the following disambiguation is too arbitrary: x + y + z -- as above -- (x + y) + z -- left-associativity of (+) -- realToFrac (x + y) + z-- injection (or treating up) done -- conservatively, i.e. only where needed Regards, Tom ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe