Re: [Haskell-cafe] Natural Numbers: Best implementation?

2009/3/12 Mark Spezzano
Hi,
I was wondering what the best way to implement Natural number would be. Is there a package which already does this?
Here are some options:
1. Don’t bother. Just use Integer.
2. Use the type
data Natural = Zero | Succ !Natural
3. Use the following definition taken from the Gentle Introduction to Haskell 98
newtype Natural = MakeNatural Integer
toNatural ::Integer-> Integer
toNatural x | x < 0 = error “Can’t create negative naturals!”
| otherwise = MakeNatural x
fromNatural :: Natural -> Integer
fromNatural (MakeNatural i) = i
and then...
instance Num Natural where
fromInteger = toNAtural
x + y = toNatural (fromNatural x + fromNatural y)
x – y = etc..
x * y = etc...
Which method is best? So far, I’ve been picking option #1 – just leaving things as they are and using Integer to keep things simple.
I’ve got that feeling that [2] would be fast and [3] would be slow. Comment appreciated on the merits of each.
Cheers,
Mark Spezzano
I would tend to use option (1) unless there's a compelling reason not to. Since naturals aren't closed under subtraction, you would in practice probably have just as many non-total functions as you would with the regular Int{,eger} type. Also, a lot of functions just take Integers so it would be more of a pain to use. In terms of speed, I think that [3] would be reasonably fast (unless you do a ton of subtraction with bounds-checking) and [2] would probably be quite slow, because you don't get the speed-boost from doing computations right on the processor. Alex

* Alexander Dunlap
Also, a lot of functions just take Integers so it would be more of a pain to use.
AFAIK there are very few fuctions that take Integers. Many functions take instances of Integral, but it's not a problem to make your own type such an instance. -- Roman I. Cheplyaka :: http://ro-che.info/ "Don't let school get in the way of your education." - Mark Twain

Am Freitag, 13. März 2009 09:21 schrieb Roman Cheplyaka:
* Alexander Dunlap
[2009-03-12 20:01:57-0700] Also, a lot of functions just take Integers so it would be more of a pain to use.
AFAIK there are very few fuctions that take Integers. Many functions take instances of Integral, but it's not a problem to make your own type such an instance.
I’d say that it is a problem. Class instances should satisfy certain laws. (Although these laws are often not stated explicitely, they are assumed to hold by users of the class and they should hold to make the instance sensible.) In the case of Num, I would expect num + negate num to equal num. This wouldn’t hold for a Natural instance of Num. Best wishes, Wolfgang

On Fri, 13 Mar 2009, Wolfgang Jeltsch wrote:
Am Freitag, 13. März 2009 09:21 schrieb Roman Cheplyaka:
* Alexander Dunlap
[2009-03-12 20:01:57-0700] Also, a lot of functions just take Integers so it would be more of a pain to use.
AFAIK there are very few fuctions that take Integers. Many functions take instances of Integral, but it's not a problem to make your own type such an instance.
I’d say that it is a problem. Class instances should satisfy certain laws. (Although these laws are often not stated explicitely, they are assumed to hold by users of the class and they should hold to make the instance sensible.) In the case of Num, I would expect num + negate num to equal num.
"equal zero" ?

Am Samstag, 14. März 2009 23:33 schrieben Sie:
On Fri, 13 Mar 2009, Wolfgang Jeltsch wrote:
Class instances should satisfy certain laws. (Although these laws are often not stated explicitely, they are assumed to hold by users of the class and they should hold to make the instance sensible.) In the case of Num, I would expect num + negate num to equal num.
"equal zero" ?
Exactly. Best wishes, Wolfgang

Am Freitag, 13. März 2009 04:01 schrieb Alexander Dunlap:
2. Use the type
data Natural = Zero | Succ !Natural
[…]
In terms of speed, I think that [3] would be reasonably fast (unless you do a ton of subtraction with bounds-checking) and [2] would probably be quite slow, because you don't get the speed-boost from doing computations right on the processor.
Not only that but also because operations like addition now take at least linear time. Best wishes, Wolfgang
participants (4)
-
Alexander Dunlap
-
Henning Thielemann
-
Roman Cheplyaka
-
Wolfgang Jeltsch