
Hi! I often stumble upon 2- (or 3-) dimensional numerical data types like (Double, Double) or similar self defined ones. I like the idea of creating instances for Num for these types. The meaning of (+), (-) and negate is clear and very intuitive, i think. I don't feel sure about (*), abs, signum and fromInteger. I used to implement fromInteger n = (r, r) where r = fromInteger n , but thinking about it, fromInteger n = (fromInteger n, 0) seems very reasonable, too. Any thoughts on that? How would you do it? btw: These are two examples i looked at in hackage: Data.Complex.Complex (which is special, cause it is mathematically defined, what (*), abs, signum and fromInteger should do (i think)) and Physics.Hipmunk.Common.Vector (http://hackage.haskell.org/packages/archive/Hipmunk/5.0.0/doc/html/Physics- Hipmunk-Common.html#9) Sönke

You are in luck!
Such an instance is very simple with Applicative. If the type you want a Num
instance for is a member of the Applicative type class you can define it
like this:
instance (Num a) => Num (Vector2 a) where
a + b = pure (+) <*> a <*> b
a - b = pure (-) <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
If you want to define a Num instance for _all_ applicatives, you can do this
(you'll need a couple extensions):
instance (Num a, Applicative f, Eq (f a), Show (f a)) => Num (f a) where
a + b = pure (+) <*> a <*> b
a - b = pure (-) <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
I am currently working on a vector and matrix library for haskell that uses
instances of this form, which you can find here:
http://github.com/jvranish/VectorMatix. The matrix half is very unfinished,
but the vector half is pretty much done.
Applicative is a pretty fantastic typeclass, it's definitly worth the time
to figure out how it works.
However, this technique won't work with tuples as they don't behave as
Functors in the way you would like. (too many type parameters, tuples don't
force all elements to be the same type so maps don't work, etc...)
Hope that helps :)
- Job
On Mon, Oct 5, 2009 at 8:40 AM, Sönke Hahn
Hi!
I often stumble upon 2- (or 3-) dimensional numerical data types like
(Double, Double)
or similar self defined ones. I like the idea of creating instances for Num for these types. The meaning of (+), (-) and negate is clear and very intuitive, i think. I don't feel sure about (*), abs, signum and fromInteger. I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it,
fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Any thoughts on that? How would you do it?
btw: These are two examples i looked at in hackage: Data.Complex.Complex (which is special, cause it is mathematically defined, what (*), abs, signum and fromInteger should do (i think))
and
Physics.Hipmunk.Common.Vector ( http://hackage.haskell.org/packages/archive/Hipmunk/5.0.0/doc/html/Physics- Hipmunk-Common.html#9http://hackage.haskell.org/packages/archive/Hipmunk/5.0.0/doc/html/Physics-%... )
Sönke _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

That's not gonna happen until when/if Haskell supports name/operator overloading. There's a scarcity of good symbols/function names and everyone wants to use them. So naturally, type class abuse follows. Regards, John A. De Goes N-Brain, Inc. The Evolution of Collaboration http://www.n-brain.net | 877-376-2724 x 101 On Oct 5, 2009, at 7:12 AM, Miguel Mitrofanov wrote:
Sönke Hahn wrote:
I used to implement fromInteger n = (r, r) where r = fromInteger n , but thinking about it, fromInteger n = (fromInteger n, 0) seems very reasonable, too.
Stop pretending something is a number when it's not. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

And what is a number? Are complex numbers numbers?
On Mon, Oct 5, 2009 at 3:12 PM, Miguel Mitrofanov
Sönke Hahn wrote:
I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it, fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Stop pretending something is a number when it's not. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

But complex numbers are just pairs of numbers. So pairs of numbers
can obviously be numbers then.
On Mon, Oct 5, 2009 at 4:40 PM, Miguel Mitrofanov
Lennart Augustsson wrote:
And what is a number?
Can't say. You know, it's kinda funny to ask a biologist what it means to be alive.
Are complex numbers numbers?
Beyond any reasonable doubt. Just like you and me are most certainly alive.

No, they aren't. They are polynomials in one variable "i" modulo i^2+1. Seriously, if you say complex numbers are just pairs of real numbers - you have to agree that double numbers (sorry, don't know the exact English term), defined by (a,b)+(c,d) = (a+c,b+d) (a,b)(c,d) = (ac, ad+bc) are just pairs of real numbers too. After that, you have two choices: a) admit that complex numbers and double numbers are the same - and most mathematicians would agree they aren't - or b) admit that the relation "be the same" is not transitive - which is simply bizarre. Lennart Augustsson wrote:
But complex numbers are just pairs of numbers. So pairs of numbers can obviously be numbers then.
On Mon, Oct 5, 2009 at 4:40 PM, Miguel Mitrofanov
wrote: Lennart Augustsson wrote:
And what is a number? Can't say. You know, it's kinda funny to ask a biologist what it means to be alive.
Are complex numbers numbers? Beyond any reasonable doubt. Just like you and me are most certainly alive.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Shouldn't the question not be "Is this a number?" but rather "What is a number?" -- I mean, from an abstract point of view, there's really no such thing, right? We have sets of things which we define an operation that has certain properties, and suddenly we start calling them numbers. Are the Symmetric groups -- which you can multiply and divide, but not add -- numbers? If they aren't, why should Z_n be numbers? What _is_ true, is that you can define a notion of addition and multiplication for both complexes and 'double' "numbers", that doesn't mean they are "numbers", rather, it means they are both Rings. Nor does it imply that they must be "the same" They are both rings over the same set of elements (Lets say, RxR), but with different operations. Furthermore, can't you construct the Rational's from the Integers in a similar way as you construct the complexes from the reals (by modding out an ideal/polynomial (resp)) -- I actually don't know for certain, we haven't gotten that far in my Alg. Class yet. :), but my intuition says that it's likely possible. Point is -- there are lots of classes for which you can implement a useful notion of addition in more than one way -- or a useful notion of some other class function (monad stuff for Lists and Ziplists, for example), but that doesn't necessarily mean that the two things are the same structure, right? /Joe On Oct 5, 2009, at 10:55 AM, Miguel Mitrofanov wrote:
No, they aren't. They are polynomials in one variable "i" modulo i^2+1.
Seriously, if you say complex numbers are just pairs of real numbers - you have to agree that double numbers (sorry, don't know the exact English term), defined by
(a,b)+(c,d) = (a+c,b+d) (a,b)(c,d) = (ac, ad+bc)
are just pairs of real numbers too. After that, you have two choices: a) admit that complex numbers and double numbers are the same - and most mathematicians would agree they aren't - or b) admit that the relation "be the same" is not transitive - which is simply bizarre.
Lennart Augustsson wrote:
But complex numbers are just pairs of numbers. So pairs of numbers can obviously be numbers then. On Mon, Oct 5, 2009 at 4:40 PM, Miguel Mitrofanov
wrote: Lennart Augustsson wrote:
And what is a number? Can't say. You know, it's kinda funny to ask a biologist what it means to be alive.
Are complex numbers numbers? Beyond any reasonable doubt. Just like you and me are most certainly alive.
_______________________________________________ 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

Complex numbers are just pairs of numbers, and then the various
operations on them are defined in a specific way.
There may be other ways to define the operations on pairs of numbers
that makes sense too.
You can also view complex numbers as polynomials if you wish. Or two
element lists of numbers.
My real point is that you shouldn't tell others what they should
regard as numbers and what not.
Being a number is in the eye of the beholder. :)
On Mon, Oct 5, 2009 at 4:55 PM, Miguel Mitrofanov
No, they aren't. They are polynomials in one variable "i" modulo i^2+1.
Seriously, if you say complex numbers are just pairs of real numbers - you have to agree that double numbers (sorry, don't know the exact English term), defined by
(a,b)+(c,d) = (a+c,b+d) (a,b)(c,d) = (ac, ad+bc)
are just pairs of real numbers too. After that, you have two choices: a) admit that complex numbers and double numbers are the same - and most mathematicians would agree they aren't - or b) admit that the relation "be the same" is not transitive - which is simply bizarre.
Lennart Augustsson wrote:
But complex numbers are just pairs of numbers. So pairs of numbers can obviously be numbers then.
On Mon, Oct 5, 2009 at 4:40 PM, Miguel Mitrofanov
wrote: Lennart Augustsson wrote:
And what is a number?
Can't say. You know, it's kinda funny to ask a biologist what it means to be alive.
Are complex numbers numbers?
Beyond any reasonable doubt. Just like you and me are most certainly alive.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 5 Oct 2009, at 19:17, Lennart Augustsson wrote:
Complex numbers are just pairs of numbers,
What about dual numbers? (Yes, I've remembered the term) Aren't they also just pairs of numbers?
There may be other ways to define the operations on pairs of numbers that makes sense too.
But these aren't the ways to define pairs of numbers, right?
My real point is that you shouldn't tell others what they should regard as numbers and what not.
Suppose somebody asks why his Haskell program doesn't work, and after some interrogation he reveals that he just renamed Program.hs to Program.exe. Shouldn't we tell him NOT to do this?
Being a number is in the eye of the beholder. :)
Yes, and some points of view aren't as good as other. That's why we have psychiatric hospitals.
On Mon, Oct 5, 2009 at 4:55 PM, Miguel Mitrofanov
wrote: No, they aren't. They are polynomials in one variable "i" modulo i^2+1.
Seriously, if you say complex numbers are just pairs of real numbers - you have to agree that double numbers (sorry, don't know the exact English term), defined by
(a,b)+(c,d) = (a+c,b+d) (a,b)(c,d) = (ac, ad+bc)
are just pairs of real numbers too. After that, you have two choices: a) admit that complex numbers and double numbers are the same - and most mathematicians would agree they aren't - or b) admit that the relation "be the same" is not transitive - which is simply bizarre.
Lennart Augustsson wrote:
But complex numbers are just pairs of numbers. So pairs of numbers can obviously be numbers then.
On Mon, Oct 5, 2009 at 4:40 PM, Miguel Mitrofanov
wrote:
Lennart Augustsson wrote:
And what is a number?
Can't say. You know, it's kinda funny to ask a biologist what it means to be alive.
Are complex numbers numbers?
Beyond any reasonable doubt. Just like you and me are most certainly alive.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

L.A. says:
complex numbers are just pairs of numbers. Later : Being a number is in the eye of the beholder. :)
Now, the readers of this forum will with horror witness a discussion about the meaning of the word "just"... American people will call it a discussion about "semantics", and we, European will not understand why this word is used in a pejorative context... "Just pairs" have no natural arithmetic upon them. All the standard set theory will not help in "making numbers", unless we inject the notion of equivalence à la Gottlob Frege. And this is surely contextual, but perhaps "the eye of the beholder" should be somehow objectivized... BTW. the missing term of M.M. is DUAL NUMBERS. Lennart continues :
Everyone agrees that the Haskell numeric hierarchy is flawed, but I've yet to see a good replacement.
There *are* some "mathematical preludes" for Haskell. There were attempts to emulate the structures of, say, the C.A.S. Magma in FP (I lost the references...) http://www.haskell.org/haskellwiki/Mathematical_prelude_discussion The problem is, that Haskell is a huge factory, people responsible NOW for its evolution have other priorities. But the story has at least 15 years. Jeroen Fokker did something then, I worked on it at the same period. Now Jacques Carette has his own system, and Sergey Mechveliani another one... But other people don't care, so the efforts are atomized. Please, keep cool. Jerzy Karczmarczuk

jerzy.karczmarczuk@info.unicaen.fr wrote:
American people will call it a discussion about "semantics", and we, European will not understand why this word is used in a pejorative context...
"Semantics" *should* be a pejorative word unless it refers to something formally specified, and preferably executable or machine-checkable. Those subtle Contintental critics of informal semantics, namely Derrida, Irigaray, et al, showed us why.

OK, "just pairs" have no arithmetic, but one way of defining
arithmetic is to treat the pairs as complex numbers. Or as mantissa
and exponent. Or as something else. So there's nothing wrong, IMO,
to make pairs an instance of Num if you so desire. (Though I'd
probably introduce a new type.)
On Mon, Oct 5, 2009 at 6:46 PM, Miguel Mitrofanov
"Just pairs" have no natural arithmetic upon them.
Exactly my point.
BTW. the missing term of M.M. is DUAL NUMBERS.
Remembered this already. Thanks anyway.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

And I agree that sometimes it can be suitable. But simply "defining an instance of Num" without a single word on the problem one is trying to solve is not just pointless. It's something that should not be done. On 5 Oct 2009, at 21:06, Lennart Augustsson wrote:
OK, "just pairs" have no arithmetic, but one way of defining arithmetic is to treat the pairs as complex numbers. Or as mantissa and exponent. Or as something else. So there's nothing wrong, IMO, to make pairs an instance of Num if you so desire. (Though I'd probably introduce a new type.)
On Mon, Oct 5, 2009 at 6:46 PM, Miguel Mitrofanov
wrote:
"Just pairs" have no natural arithmetic upon them.
Exactly my point.
BTW. the missing term of M.M. is DUAL NUMBERS.
Remembered this already. Thanks anyway.
_______________________________________________ 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

On 5 Oct 2009, at 21:06, Lennart Augustsson wrote:
OK, "just pairs" have no arithmetic, but one way of defining arithmetic is to treat the pairs as complex numbers. Or as mantissa and exponent. Or as something else. So there's nothing wrong, IMO, to make pairs an instance of Num if you so desire. (Though I'd probably introduce a new type.)
I was looking for one intuitive way of instantiating pairs of numbers as Num. One where i wouldn't have to look in the documentation to remember what (+) does. So considering all these examples of what pairs of numbers could be, i agree with Miguel Mitrofanov: "It's something that should not be done." Two questions remain, i think: 1. How can i have some notion of addition and subtraction for something that i don't want to put in the Num class? That's easy: I could just write a class that defines binary operators (like (+~) and (-~), for example). I don't get the fanciness of (+), but that's okay. 2. How can i use numeric literals to construct values, whose types are not in the Num class? Haskell could provide a class IsNumber (like IsString for string literals). Is that something we would want? BTW, interesting discussion, thanks! Sönke On Monday 05 October 2009 07:24:37 pm Miguel Mitrofanov wrote:
And I agree that sometimes it can be suitable.
But simply "defining an instance of Num" without a single word on the problem one is trying to solve is not just pointless. It's something that should not be done.
On Mon, Oct 5, 2009 at 6:46 PM, Miguel Mitrofanov
wrote:
"Just pairs" have no natural arithmetic upon them.
Exactly my point.
BTW. the missing term of M.M. is DUAL NUMBERS.
Remembered this already. Thanks anyway.
_______________________________________________ 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

On Mon, Oct 5, 2009 at 11:02 AM, Sönke Hahn
On 5 Oct 2009, at 21:06, Lennart Augustsson wrote:
OK, "just pairs" have no arithmetic, but one way of defining arithmetic is to treat the pairs as complex numbers. Or as mantissa and exponent. Or as something else. So there's nothing wrong, IMO, to make pairs an instance of Num if you so desire. (Though I'd probably introduce a new type.)
I was looking for one intuitive way of instantiating pairs of numbers as Num. One where i wouldn't have to look in the documentation to remember what (+) does. So considering all these examples of what pairs of numbers could be, i agree with Miguel Mitrofanov: "It's something that should not be done."
Two questions remain, i think:
1. How can i have some notion of addition and subtraction for something that i don't want to put in the Num class?
That's easy: I could just write a class that defines binary operators (like (+~) and (-~), for example). I don't get the fanciness of (+), but that's okay.
I don't know how well it works in practice, but you could hide the prelude in your module and then import it qualified. This would allow your module to redefine the normal symbols as the operators you want them to be.
2. How can i use numeric literals to construct values, whose types are not in the Num class?
This I don't know how to do without a pre-processor or maybe Template Haskell would work.
Haskell could provide a class IsNumber (like IsString for string literals). Is that something we would want?
Seems like IsBoolean would also be useful if you went this route. And perhaps, IsList :) I'm sure we could think of more. I can see how they would be handy for anyone making an eDSL, especially if combine with view patterns. Jason

On Mon, 5 Oct 2009, Jason Dagit wrote:
2. How can i use numeric literals to construct values, whose types are not in the Num class?
Numeric literals are treated as Integer or Rational, and are then converted with the function fromInteger or fromRational, respectively, to the required type. Whatever fromInteger function is in scope, will be used. If fromInteger is in a class other than Num (in NumericPrelude it is Ring, but it can be also a function that is not a class method), then number literals have a type like: 2 :: MyNumClass a => a

Hi,
On Tue, Oct 6, 2009 at 2:37 AM, Henning Thielemann
Numeric literals are treated as Integer or Rational, and are then converted with the function fromInteger or fromRational, respectively, to the required type. Whatever fromInteger function is in scope, will be used. If fromInteger is in a class other than Num (in NumericPrelude it is Ring, but it can be also a function that is not a class method), then number literals have a type like: 2 :: MyNumClass a => a
This is only the case if you use GHC's NoImplicitPrelude extension, otherwise the "fromInteger" of the Prelude is used, even if it is not in scope. Here is an example: module A where boolLit :: Integer -> Bool boolLit 0 = False boolLit _ = True {-# LANGUAGE NoImplicitPrelude #-} module Main where import A(boolLit) import Prelude(Integer,Bool,print) fromInteger :: Integer -> Bool fromInteger = boolLit main = print 0 Note that 0 means different things in the different modules! -Iavor

On Oct 6, 2009, at 3:49 AM, Lennart Augustsson wrote:
But complex numbers are just pairs of numbers. So pairs of numbers can obviously be numbers then.
The basic problem here is that pairs of numbers can be made to fit into the Haskell framework with more than one semantics. For example, historically one use for a pair of floating point numbers was to get twice the precision. You implement the operations for that use very differently from the use as complex numbers. If you *know* what you want each of the operations to mean, go ahead. If you don't know, if you have to define some operation just to satisfy the typeclass requirements, and aren't sure what to do in some case, you probably shouldn't use that typeclass.

Miguel Mitrofanov rebukes Sönke Hahn, who -:
wrote:
I used to implement fromInteger n = (r, r) where r = fromInteger n , but thinking about it, fromInteger n = (fromInteger n, 0) seems very reasonable, too.
Stop pretending something is a number when it's not.
Miguel Mitrofanov, please kindly stop pretending that you KNOW what is a number, and what is not. The numeric classes in standard Haskell are disgraceful, and the idea that if something can be added, it is a number is bad. Vectors are not numbers, but inventing "special" (+) for all kinds of Abelian additions is awkward. So, people call "numbers" what they wish, and it is *their* business. I needed to add functions (of course, without Eq nor Show membership), I had to fake... Pairs (a,b) may be "numbers" in various contexts, for example (value,derivative) in automatic differentiation. Or (mainTerm,otherOrders) in some infinitesimal calculus. Or pairs (scalar, 3vector) for quaternions. The idea of putting fromInteger in the same class, is a design bug (my personal opinion, of course). There are plenty of examples where conversions from integers are legitimate, but no addition or (*)seem natural. Or the other way round ; apparently Sönke Hahn is in that situation, so he fakes... Jerzy Karczmarczuk

Miguel Mitrofanov, please kindly stop pretending that you KNOW what is a number, and what is not.
Never said that. Sometimes it's debatable. But if you can't figure out a way to multiply things so that it would make some kind of sense - you haven't made them numbers (yet).
The numeric classes in standard Haskell are disgraceful, and the idea that if something can be added, it is a number is bad.
Which is kinda my point.
So, people call "numbers" what they wish, and it is *their* business.
I'm not sure what do you mean here. Of course, it's OK to call anything "numbers" provided that you stated explicitly what exactly you would mean by that. But then you have to drop all kind of stuff mathematicians developed for the usual notion of numbers. In the same way, you shouldn't use the "Num" class for your "numbers". On the other hand, people can (ab)use the "Num" class as they wish, and it's their business until they ask a question about it somewhere outside - which makes the business not only theirs.
Pairs (a,b) may be "numbers" in various contexts, for example (value,derivative) in automatic differentiation. Or (mainTerm,otherOrders) in some infinitesimal calculus. Or pairs (scalar, 3vector) for quaternions.
Or (real, imaginary) for complex numbers. That's right. All these notions are very different - which is why "pairs of numbers" are NOT numbers - but "complex numbers" are, as well as "value-derivative pairs". Isn't that what we have newtypes for?
There are plenty of examples where conversions from integers are legitimate, but no addition or (*)seem natural.
Certainly. I think it's commonplace that numerical classes in Haskell Prelude are not exactly an example of perfect design. Still, it doesn't make it good to abuse classes like "Num" just because we want a fancy plus sign.

In what way is it not a number?
data MyNumber a = MyNum a a
deriving (Show, Eq)
instance Functor MyNum where
fmap f (MyNum a b) = MyNum (f a) (f b)
instance Applicative MyNum where
pure a = MyNum a a
MyNum f g <*> MyNum a b = MyNum (f a) (g b)
instance (Num a) => Num (MyNum a) where
a + b = pure (+) <*> a <*> b
a - b = pure (-) <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
This instance obeys the commutative, distributive, and associative laws,
and the multiplicative, and additive identities. (at least, if the numbers
it contains satisfy those laws)
How is MyNum not a number?
Sönke Hahn:
btw, I forgot to mention in my first email, but
fromInteger n = (r, r) where r = fromInteger n
is better than:
fromInteger n = (fromInteger n, 0)
as you get a lot of corner cases otherwise.
I use fromInteger = pure . fromInteger, which when combined with my
Applicative instance, is effectively the same as your: fromInteger n = (r,
r) where r = fromInteger n
- Job
On Mon, Oct 5, 2009 at 9:12 AM, Miguel Mitrofanov
Sönke Hahn wrote:
I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it, fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Stop pretending something is a number when it's not.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Montag 05 Oktober 2009 16:29:02 schrieb Job Vranish:
In what way is it not a number?
If there's a natural[1] implementation of fromInteger, good. If there isn't, *don't provide one*. fromInteger _ = error "Not sensible" is better than doing something strange. [1] In the case of residue class rings, you may choose between restricting the range of legitimate arguments for fromInteger or doing a modulo operation on the argument, both ways are natural and meet expectations sufficiently well.
Sönke Hahn: btw, I forgot to mention in my first email, but fromInteger n = (r, r) where r = fromInteger n is better than: fromInteger n = (fromInteger n, 0) as you get a lot of corner cases otherwise.
I use fromInteger = pure . fromInteger, which when combined with my Applicative instance, is effectively the same as your: fromInteger n = (r, r) where r = fromInteger n
- Job
On Mon, Oct 5, 2009 at 9:12 AM, Miguel Mitrofanov
wrote: Sönke Hahn wrote:
I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it, fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Stop pretending something is a number when it's not.

Daniel Fischer wrote:
Am Montag 05 Oktober 2009 16:29:02 schrieb Job Vranish:
In what way is it not a number?
If there's a natural[1] implementation of fromInteger, good. If there isn't, *don't provide one*. fromInteger _ = error "Not sensible" is better than doing something strange.
[1] In the case of residue class rings, you may choose between restricting [the range of legitimate arguments for fromInteger or doing a modulo operation on the argument, both ways are natural and meet expectations sufficiently well.
More generally, any ring with multiplicative unit (let's call it 'one') will do. If there were 'one' and 'zero' methods in class Num, we could even give a default implementation (however inefficient) as fromInteger n | n < 0 = negate (fromInteger n) fromInteger n | n > 0 = one + fromInteger (n-1) fromInteger _ = zero In fact, I'd argue that the existence of fromInteger in class Num "morally" implies a unit for multiplication (namely 'fromInteger 1'), otherwise fromInteger isn't even a ring morphism. Cheers Ben

On Wed, Oct 7, 2009 at 12:08 PM, Ben Franksen
More generally, any ring with multiplicative unit (let's call it 'one') will do.
Isn't that every ring? As I understand it, the multiplication in a
ring is required to form a monoid.
--
Dave Menendez

A ring is an abelian group in addition, with the added operation (*) being distributive over addition, and 0 annihilating under multiplication. (*) is also associative. Rings don't necessarily need _multiplicative_ id, only _additive_ id. Sometimes Rings w/o ID is called a Rng (a bit of a pun). /Joe On Oct 7, 2009, at 4:41 PM, David Menendez wrote:
On Wed, Oct 7, 2009 at 12:08 PM, Ben Franksen
wrote: More generally, any ring with multiplicative unit (let's call it 'one') will do.
Isn't that every ring? As I understand it, the multiplication in a ring is required to form a monoid.
-- Dave Menendez
http://www.eyrie.org/~zednenem/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Mittwoch 07 Oktober 2009 22:44:19 schrieb Joe Fredette:
A ring is an abelian group in addition, with the added operation (*) being distributive over addition, and 0 annihilating under multiplication. (*) is also associative. Rings don't necessarily need _multiplicative_ id, only _additive_ id. Sometimes Rings w/o ID is called a Rng (a bit of a pun).
/Joe
In my experience, the definition of a ring more commonly includes the multiplicative identity and abelian groups with an associative multiplication which distributes over addition are called semi-rings. There is no universally employed definition (like for natural numbers, is 0 included or not; fields, is the commutativity of multiplication part of the definition or not; compactness, does it include Hausdorff or not; ...).

I was just quoting from Hungerford's Undergraduate text, but yes, the "default ring" is in {Rng, Ring}, I haven't heard semirings used in the sense of a Rng. I generally find semirings defined as a ring structure without additive inverse and with 0-annihilation (which one has to assume in the case of SRs, I included it in my previous definition because I wasn't sure if I could prove it via the axioms, I think it's possible, but I don't recall the proof). Wikipedia seems to agree with your definition, though it does have a note which says some authors use the definition of Abelian Group + Semigroup (my definition) as opposed to Abelian Group + Monoid (your defn). Relevant: http://en.wikipedia.org/wiki/Semiring http://en.wikipedia.org/wiki/Ring_(algebra) http://en.wikipedia.org/wiki/Ring_(algebra)#Notes_on_the_definition /Joe On Oct 7, 2009, at 5:41 PM, Daniel Fischer wrote:
Am Mittwoch 07 Oktober 2009 22:44:19 schrieb Joe Fredette:
A ring is an abelian group in addition, with the added operation (*) being distributive over addition, and 0 annihilating under multiplication. (*) is also associative. Rings don't necessarily need _multiplicative_ id, only _additive_ id. Sometimes Rings w/o ID is called a Rng (a bit of a pun).
/Joe
In my experience, the definition of a ring more commonly includes the multiplicative identity and abelian groups with an associative multiplication which distributes over addition are called semi-rings.
There is no universally employed definition (like for natural numbers, is 0 included or not; fields, is the commutativity of multiplication part of the definition or not; compactness, does it include Hausdorff or not; ...). _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Mittwoch 07 Oktober 2009 23:51:54 schrieb Joe Fredette:
I was just quoting from Hungerford's Undergraduate text, but yes, the "default ring" is in {Rng, Ring}, I haven't heard semirings used in the sense of a Rng.
It's been looong ago, I seem to have misremembered :? But there used to be a german term for Rngs, and it was neither Pseudoring nor quasiring, so I thought it was Halbring.
I generally find semirings defined as a ring structure without additive inverse and with 0-annihilation (which one has to assume in the case of SRs, I included it in my previous definition because I wasn't sure if I could prove it via the axioms, I think it's possible, but I don't recall the proof).
0*x = (0+0)*x = 0*x + 0*x ==> 0*x = 0
Wikipedia seems to agree with your definition, though it does have a note which says some authors use the definition of Abelian Group + Semigroup (my definition) as opposed to Abelian Group + Monoid (your defn).
Relevant:
http://en.wikipedia.org/wiki/Semiring http://en.wikipedia.org/wiki/Ring_(algebra) http://en.wikipedia.org/wiki/Ring_(algebra)#Notes_on_the_definition
/Joe
On Oct 7, 2009, at 5:41 PM, Daniel Fischer wrote:
Am Mittwoch 07 Oktober 2009 22:44:19 schrieb Joe Fredette:
A ring is an abelian group in addition, with the added operation (*) being distributive over addition, and 0 annihilating under multiplication. (*) is also associative. Rings don't necessarily need _multiplicative_ id, only _additive_ id. Sometimes Rings w/o ID is called a Rng (a bit of a pun).
/Joe
In my experience, the definition of a ring more commonly includes the multiplicative identity and abelian groups with an associative multiplication which distributes over addition are called semi-rings.
There is no universally employed definition (like for natural numbers, is 0 included or not; fields, is the commutativity of multiplication part of the definition or not; compactness, does it include Hausdorff or not; ...).

Daniel Fischer wrote:
Am Mittwoch 07 Oktober 2009 23:51:54 schrieb Joe Fredette:
I generally find semirings defined as a ring structure without additive inverse and with 0-annihilation (which one has to assume in the case of SRs, I included it in my previous definition because I wasn't sure if I could prove it via the axioms, I think it's possible, but I don't recall the proof).
0*x = (0+0)*x = 0*x + 0*x ==> 0*x = 0
This proof only works if your additive monoid is cancellative, which
need not be true in a semiring. The natural numbers extended with
infinity is one example (if you don't take 0*x = 0 as an axiom, I think
there are two possibilities for 0*∞).
--
Jason McCarty

On Wed, Oct 07, 2009 at 08:44:27PM -0400, Jason McCarty wrote:
Daniel Fischer wrote:
Am Mittwoch 07 Oktober 2009 23:51:54 schrieb Joe Fredette:
I generally find semirings defined as a ring structure without additive inverse and with 0-annihilation (which one has to assume in the case of SRs, I included it in my previous definition because I wasn't sure if I could prove it via the axioms, I think it's possible, but I don't recall the proof).
0*x = (0+0)*x = 0*x + 0*x ==> 0*x = 0
This proof only works if your additive monoid is cancellative, which need not be true in a semiring. The natural numbers extended with infinity is one example (if you don't take 0*x = 0 as an axiom, I think there are two possibilities for 0*∞).
Given that x = 1*x = (0+1)*x = 0*x + 1*x = 0*x + x we can show that x = x + 0*x (right) x = 0*x + x (left) so, by definition of 'zero', we have that 0*x is a zero. But we can easily prove that there can be only one zero: suppose we have two zeros z1 and z2; it follows that z1 = z1 + z2 = z2 So 0*x = 0. Any flaws? -- Felipe.

Am Donnerstag 08 Oktober 2009 03:05:13 schrieb Felipe Lessa:
On Wed, Oct 07, 2009 at 08:44:27PM -0400, Jason McCarty wrote:
Daniel Fischer wrote:
Am Mittwoch 07 Oktober 2009 23:51:54 schrieb Joe Fredette:
I generally find semirings defined as a ring structure without additive inverse and with 0-annihilation (which one has to assume in the case of SRs, I included it in my previous definition because I wasn't sure if I could prove it via the axioms, I think it's possible, but I don't recall the proof).
0*x = (0+0)*x = 0*x + 0*x ==> 0*x = 0
This proof only works if your additive monoid is cancellative, which need not be true in a semiring. The natural numbers extended with infinity is one example (if you don't take 0*x = 0 as an axiom, I think there are two possibilities for 0*∞).
It was a proof for a ring (with or without unit), which Joe stated above he didn't recall. There your additive monoid is cancellative since it's a group :D
Given that
x = 1*x = (0+1)*x = 0*x + 1*x = 0*x + x
we can show that
x = x + 0*x (right) x = 0*x + x (left)
so, by definition of 'zero', we have that 0*x is a zero.
Not necessarily, we don't know 0*x + y = y for arbitrary y yet. If the additive monoid isn't cancellative, that needn't be the case. In Jason's example, you can indeed set 0*∞ = ∞.
But we can easily prove that there can be only one zero: suppose we have two zeros z1 and z2; it follows that
z1 = z1 + z2 = z2
So 0*x = 0. Any flaws?
-- Felipe.

Joe Fredette wrote:
A ring is an abelian group in addition, with the added operation (*) being distributive over addition, and 0 annihilating under multiplication. (*) is also associative. Rings don't necessarily need _multiplicative_ id, only _additive_ id.
Yes, this is how I learned it in my Algebra course(*). Though I can imagine that this is not universally agreed upon; indeed most of the more interesting results need a multiplicative unit, IIRC, so there's a justification for authors to include it in the basic definition (so they don't have to say let-R-be-a-ring-with-multiplicative-unit all the time ;-) Cheers Ben (*) As an aside, this was given by one Gernot Stroth, back then still at the FU Berlin, of whom I later learned that he took part in the grand effort to classify the simple finite groups. The course was extremely tight but it was fun and I never again learned so much in one semester.

Sönke Hahn schrieb:
Hi!
I often stumble upon 2- (or 3-) dimensional numerical data types like
(Double, Double)
or similar self defined ones. I like the idea of creating instances for Num for these types. The meaning of (+), (-) and negate is clear and very intuitive, i think. I don't feel sure about (*), abs, signum and fromInteger. I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it,
fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Any thoughts on that? How would you do it?
I use NumericPrelude that has more fine grained type classes. E.g. (+) is in Additive and (*) is in Ring. http://hackage.haskell.org/package/numeric-prelude

On Monday 05 October 2009 10:14:02 pm Henning Thielemann wrote:
Sönke Hahn schrieb:
Hi!
I often stumble upon 2- (or 3-) dimensional numerical data types like
(Double, Double)
or similar self defined ones. I like the idea of creating instances for Num for these types. The meaning of (+), (-) and negate is clear and very intuitive, i think. I don't feel sure about (*), abs, signum and fromInteger. I used to implement
fromInteger n = (r, r) where r = fromInteger n
, but thinking about it,
fromInteger n = (fromInteger n, 0)
seems very reasonable, too.
Any thoughts on that? How would you do it?
I use NumericPrelude that has more fine grained type classes. E.g. (+) is in Additive and (*) is in Ring.
That is pretty cool, thanks. How do your import statements look like, when you use numeric-prelude? Mine look a bit ugly: import Prelude hiding ((+), (-), negate) import Algebra.Additive ((+), (-), negate) Sönke

On Mon, 5 Oct 2009, Soenke Hahn wrote:
On Monday 05 October 2009 10:14:02 pm Henning Thielemann wrote:
I use NumericPrelude that has more fine grained type classes. E.g. (+) is in Additive and (*) is in Ring.
That is pretty cool, thanks. How do your import statements look like, when you use numeric-prelude? Mine look a bit ugly:
import Prelude hiding ((+), (-), negate) import Algebra.Additive ((+), (-), negate)
{-# LANGUAGE NoImplicitPrelude #-} or import Prelude () and import qualified Algebra.Additive as Additive (e.g. for Additive.C) import NumericPrelude import PreludeBase The first form is necessary if you use number literals, what is the case for you I think.

On Monday 05 October 2009 11:58:28 pm Henning Thielemann wrote:
On Mon, 5 Oct 2009, Soenke Hahn wrote:
On Monday 05 October 2009 10:14:02 pm Henning Thielemann wrote:
I use NumericPrelude that has more fine grained type classes. E.g. (+) is in Additive and (*) is in Ring.
That is pretty cool, thanks. How do your import statements look like, when you use numeric-prelude? Mine look a bit ugly:
import Prelude hiding ((+), (-), negate) import Algebra.Additive ((+), (-), negate)
{-# LANGUAGE NoImplicitPrelude #-}
or
import Prelude ()
and
import qualified Algebra.Additive as Additive (e.g. for Additive.C) import NumericPrelude import PreludeBase
The first form is necessary if you use number literals, what is the case for you I think.
Thanks. If you want to use number literals, you have to implement an instance for Algebra.Ring.C, if i understand correctly. Is there any special reason, why fromInteger is a method of Algebra.Ring.C? Sönke

Soenke Hahn schrieb:
If you want to use number literals, you have to implement an instance for Algebra.Ring.C, if i understand correctly. Is there any special reason, why fromInteger is a method of Algebra.Ring.C?
Yes, Ring is the most basic class in the hierarchy that provides a zero, a one and addition, thus you could implement fromInteger by successively adding or subtracting one from zero, given some basic operations on Integer. 'fromInteger' just allows a more efficient implementation.
participants (18)
-
Anton van Straaten
-
Ben Franksen
-
Daniel Fischer
-
David Menendez
-
Felipe Lessa
-
Henning Thielemann
-
Iavor Diatchki
-
Jason Dagit
-
Jason McCarty
-
jerzy.karczmarczuk@info.unicaen.fr
-
Job Vranish
-
Joe Fredette
-
John A. De Goes
-
Lennart Augustsson
-
Miguel Mitrofanov
-
Richard O'Keefe
-
Soenke Hahn
-
Sönke Hahn