Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-21 Thread Yitzchak Gale
I wrote:

Yitzchak Gale wrote:
 So why not make the laziness available
 also for cases where 1 - 2 == 0 does _not_ do
 the right thing?
 data LazyInteger = IntZero | IntSum Bool Integer LazyInteger
 or
 data LazyInteger = LazyInteger Bool Nat
 or whatever.

Luke Palmer wrote:
 data LazyInteger = IntDiff Nat Nat
 The only value which would diverge when
 compared to a constant would be infinity - infinity.

Hmm. But then you could have integers that are
divergent and non-infinite. What do we gain by
doing it this way?

-Yitz
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-20 Thread Luke Palmer
On 10/19/07, Yitzchak Gale [EMAIL PROTECTED] wrote:
 So why not make the laziness available
 also for cases where 1 - 2 == 0 does _not_ do
 the right thing?

 data LazyInteger = IntZero | IntSum Bool Integer LazyInteger

 or

 data LazyInteger = LazyInteger Bool Nat

I think

data LazyInteger = IntDiff Nat Nat

would admit implementation of most of the nice properties of this
implementation.  Comparison operators could short circuit when one of
the two naturals is zero.  The only  value which would diverge when
compared to a constant would be infinity - infinity.

Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-19 Thread Yitzchak Gale
Hi John,

I wrote:
 - Zero really means 0, not 0 or negative

You wrote:
 Actually, zero does mean zero. There is no such thing as negative
 numbers in the naturals so it doesn't make sense to say '0 or negative'.

Well, then, 0 or error, or 0 or nothing. It clearly
does not mean zero.

 Subtraction is necessarily defined differently of course.

As described in the referenced paper,
(yes, an enjoyable read, thanks) this is for
convenience only. No one is claiming that 1 - 2 == 0
in the naturals. It is just undefined. But we
find that returning Zero rather than raising
an exception happens to do the right thing for
certain common usages of the naturals.

Anyway, my point is that you have done two good
things here that are orthogonal to each other:
a good lazy integral type, and a good naturals type.

So why not make the laziness available
also for cases where 1 - 2 == 0 does _not_ do
the right thing?

data LazyInteger = IntZero | IntSum Bool Integer LazyInteger

or

data LazyInteger = LazyInteger Bool Nat

or whatever.

Thanks,
Yitz
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-18 Thread Yitzchak Gale
I wrote:
 Nice, lots of fun!
 Wouldn't it be more convenient to allow them
 to be signed?

John Meacham wrote:
 Well, a couple reasons. One is that Natural numbers are a pretty useful
 type in and of themselves, often times when used with lazy evaluation.
 The other is that it is unclear what semantics lazy signed numbers would
 have...

True. I was thinking of the sign at the beginning - which
means, essentially, the same as what you already have.
The real only differences are:

- Zero really means 0, not 0 or negative.
- In certain special cases where you happen to know that
  the result should be a certain negative number, you get that

In particular, the scrictness properties - which you have already
so carefully worked out for the case of the naturals -
do not change.

Of course, you can then easily restrict to the naturals
when you want that.

-Yitz
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-18 Thread John Meacham
On Thu, Oct 18, 2007 at 01:58:14PM +0200, Yitzchak Gale wrote:
 - Zero really means 0, not 0 or negative.

Actually, zero does mean zero. There is no such thing as negative
numbers in the naturals so it doesn't make sense to say '0 or negative'.

Subtraction is necessarily defined differently of course. As in, a
natural number type was actually my goal as it is the natural choice
for a lot of operations (hah! pun!), it wasn't a concession. 

I found the paper that originally inspired me to write this class:
http://citeseer.ist.psu.edu/45669.html

it is a good read.

John


-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-17 Thread Henning Thielemann

On Tue, 16 Oct 2007, Peter Verswyvelen wrote:

 Concurrent Clean uses the ~ symbol for unary negation. That's also a way
 of fixing it.

 Personally I could also live with allowing no space between the minus
 sign and the number... If you leave a space, - becomes the subtract
 operator.

Me seems, that this discussion came up several times:
  http://www.haskell.org/haskellwiki/Unary_minus
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-17 Thread Peter Verswyvelen
Duh, you're right... silly me. I always put spaces between the operator, 
but many people of course don't.


Isaac Dupree wrote:

Peter Verswyvelen wrote:
Personally I could also live with allowing no space between the minus 
sign and the number... If you leave a space, - becomes the subtract 
operator.


I once thought that... there was the opposition that (x-1) subtraction 
of a constant appears too often.  And I found that I myself wrote that 
several times.  And saying whitespace on the left but not the right 
seems too complicated for Haskell lexer semantics.  So the current 
situation is just unhappy, that's all. (and maybe compiler warnings 
could still be implemented)


Isaac
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-17 Thread Peter Verswyvelen

Yes, I guessed it would.

Actually logging all those discussions is a good idea: I will make a 
wiki page containing all the discussions I have with my wife, and then - 
at the start of a new discussion - I can redirect her to the wiki page. 
Problem solved, no energy wasted ;-) 


Okay, seriously OT...

Henning Thielemann wrote:

On Tue, 16 Oct 2007, Peter Verswyvelen wrote:

  

Concurrent Clean uses the ~ symbol for unary negation. That's also a way
of fixing it.

Personally I could also live with allowing no space between the minus
sign and the number... If you leave a space, - becomes the subtract
operator.



Me seems, that this discussion came up several times:
  http://www.haskell.org/haskellwiki/Unary_minus


  


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread Yitzchak Gale
John Meacham wrote:
 if anyone is interested, Although I bet this has been implemented a
 hundred times over, I have attached my lazy naturals module below just
 for larks.

Nice, lots of fun!

Wouldn't it be more convenient to allow them
to be signed? True, you can't have laziness in
certain cases, and certain calculations would
be non-convergent. But you already have
things like that, e.g subtraction, and natEven.

 Anyone have any comments on my lazy multiplication algorithm?

Looks fine to me. It introduces left-bias, but you have
to do it one way or the other.

 since (+) is lazy, we can still get a good lazy result without
 evaluating the tails when multiplying... that is nice.

Yes.

 n `mod` 0 should be?

It's negative infinity if n  0, but you don't
allow negative numbers. I suppose it should
be Zero - in your implementation, Zero does
not exactly have the semantics of 0. Instead,
it means either 0 or negative.

 If anyone wants me to clean this up and package it as a real module, I
 would be happy to do so.

Please at least post it to the wiki.

 sorry for the tangent. just one of those days.

I know the feeling... :)

Thanks,
Yitz
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread Stuart Cook
On 10/17/07, John Meacham [EMAIL PROTECTED] wrote:
 if anyone is interested, Although I bet this has been implemented a
 hundred times over, I have attached my lazy naturals module below just
 for larks. It is quite efficient as such things go and very lazy. for
 instance (genericLength xs  5) will only evaluate up to the 5th element
 of the list before returning a result. and ((1 `div` 0)  17) is true,
 not bottom.

 If anyone wants me to clean this up and package it as a real module, I
 would be happy to do so.

It looks like there's already a lazy-natural type in the numbers
package on Hackage, but not having used it I have no idea what it's
like.

http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers-2007.9.25
http://tinyurl.com/2pmthz


Stuart
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread Lennart Augustsson
The one in the numbers package is not quite as clever as John's; it's the
naïve version of lazy naturals.

On 10/17/07, Stuart Cook  [EMAIL PROTECTED] wrote:

 On 10/17/07, John Meacham  [EMAIL PROTECTED] wrote:
  if anyone is interested, Although I bet this has been implemented a
  hundred times over, I have attached my lazy naturals module below just
  for larks. It is quite efficient as such things go and very lazy. for
  instance (genericLength xs  5) will only evaluate up to the 5th element
  of the list before returning a result. and ((1 `div` 0)  17) is true,
  not bottom.

  If anyone wants me to clean this up and package it as a real module, I
  would be happy to do so.

 It looks like there's already a lazy-natural type in the numbers
 package on Hackage, but not having used it I have no idea what it's
 like.


 http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers-2007.9.25
 http://tinyurl.com/2pmthz


 Stuart
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread John Meacham
On Wed, Oct 17, 2007 at 12:41:54PM +0200, Yitzchak Gale wrote:
 John Meacham wrote:
  if anyone is interested, Although I bet this has been implemented a
  hundred times over, I have attached my lazy naturals module below just
  for larks.
 
 Nice, lots of fun!
 
 Wouldn't it be more convenient to allow them
 to be signed? True, you can't have laziness in
 certain cases, and certain calculations would
 be non-convergent. But you already have
 things like that, e.g subtraction, and natEven.

Well, a couple reasons. One is that Natural numbers are a pretty useful
type in and of themselves, often times when used with lazy evaluation.
The other is that it is unclear what semantics lazy signed numbers would
have, if the sign were at the beginning, then addition and subtraction
would be strict, because you can't figure out the sign of the result
without running through to the end of the number. Another possibility
which would preserve full lazyness is
to just allow negative numbers in Sum. which has other issues, such as
you no longer have the property that

Sum x (Sum _ _)  Sum x Zero

so you couldn't short circuit comparison operations.

All in all, it wasn't clear what the correct tradeoffs would be and I
wanted numbers restricted to naturals as much as I wanted lazy numbers. 

  Anyone have any comments on my lazy multiplication algorithm?
 
 Looks fine to me. It introduces left-bias, but you have
 to do it one way or the other.

Yeah, It was fairly subtle, I tried various permutations of making it
strict or lazy and removing the bias. I can't say I fully understand why
this form is the best. something odd is that If I don't rebuild the
second argument (y + ry) but use the original second value placed in, it
drastically slows things down.

  since (+) is lazy, we can still get a good lazy result without
  evaluating the tails when multiplying... that is nice.
 
 Yes.
 
  n `mod` 0 should be?
 
 It's negative infinity if n  0, but you don't
 allow negative numbers. I suppose it should
 be Zero - in your implementation, Zero does
 not exactly have the semantics of 0. Instead,
 it means either 0 or negative.

yes. something like that, I read a paper somewhere that defined negative 



  If anyone wants me to clean this up and package it as a real module, I
  would be happy to do so.
 
 Please at least post it to the wiki.

okay, I will clean it up some and add more documentation as to the
strictness. In general, I tried to make everything 'head-strict' in both
arguments, but symmetrically 'tail-lazy'. if that makes sense at all. I
need to come up with some better terminology.

also, div is tail-lazy, but mod is tail-strict.

I have found assymetric addition to be useful actually and will export
it as a separate function, where instead of 'zipping' the two lazy
numbers together, it appends the second to the first, making it fully
lazy in the second argument. It is mainly useful for tying the knot to
make infinite numbers, but can sometimes affect 

hmm.. is there any established terminology for this sort of thing? my
thought is something like:

lazy - fully lazy, _|_ and Infinity can be passed in.

tail-lazy - can produce results without traversing the whole number,
such as division, addition, and multiplication, Infinity can safely be passed 
in.

head-strict - you can't pass in _|_, but you may or may not be able to pass in
Infinity

fully strict - you can't pass in _|_ or Infinity and expect a result.
'mod' is an example. 

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread John Meacham
On Wed, Oct 17, 2007 at 09:16:47PM +0100, Lennart Augustsson wrote:
 The one in the numbers package is not quite as clever as John's; it's the
 naïve version of lazy naturals.

it appears to also be left biased in general, mine are symmetric and
commutative whenever possible and things like its division arn't lazy
when they could be (since it computes the modulus at the same time). 

Another difference is that I use capping behavior at zero rather than
producing an error. This has a variety of nice algebraic properties (in
addition to not bottoming out). unfortunately I can't find the paper
that I read about them at the moment hmm...

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread David Benbennick
This module doesn't appear to be very lazy to me.  For example, in ghci,

*Util.LazyNum List genericLength (1:2:undefined)  (1 :: Nat)
*** Exception: Prelude.undefined

How is this module intended to be used?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread John Meacham
On Wed, Oct 17, 2007 at 05:43:08PM -0700, David Benbennick wrote:
 This module doesn't appear to be very lazy to me.  For example, in ghci,
 
 *Util.LazyNum List genericLength (1:2:undefined)  (1 :: Nat)
 *** Exception: Prelude.undefined
 
 How is this module intended to be used?

Oops, sorry, the version I posted was an intermediate one that had a
different addition algorithm. here is a better one that fixes that issue:

Zero + y = y
Sum x n1 + y = Sum x (y + n1)  

note that it alternates the order in the recursive call, interleaving
the elements of the two arguments.

so, this is head-strict in the left argument, but tail-lazy in both. 

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-17 Thread David Benbennick
On 10/17/07, John Meacham [EMAIL PROTECTED] wrote:
 Oops, sorry, the version I posted was an intermediate one that had a
 different addition algorithm. here is a better one that fixes that issue:

 Zero + y = y
 Sum x n1 + y = Sum x (y + n1)

 note that it alternates the order in the recursive call, interleaving
 the elements of the two arguments.

Thanks.

Have you thought at all about how to make maximally lazy Naturals?
For example, a data type that can answer True to both

genericLength (1:undefined) + genericLength (1:2:3:4:5:6:undefined)  (6 :: Nat)

genericLength (1:2:3:4:5:6:undefined) + genericLength (1:undefined)  (6 :: Nat)

Is that a desired feature?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Neil Mitchell
Hi

  (/ 10) means the function that divides its argument by 10
  (- 10) however is just the number -10, even if I put a space between the -
 and 10.

  How can I create a function that subtracts 10 from its argument in a clean
 way then?

subtract is the way to go. (`subtract` 10)

I think you should have to write negative numbers using the syntax
0-10, since currently having one single unary operator is ugly.

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Derek Elkins
On Tue, 2007-10-16 at 17:02 +0100, Neil Mitchell wrote:
 Hi
 
   (/ 10) means the function that divides its argument by 10
   (- 10) however is just the number -10, even if I put a space between the -
  and 10.
 
   How can I create a function that subtracts 10 from its argument in a clean
  way then?
 
 subtract is the way to go. (`subtract` 10)

subtract 10 not (`subtract` 10) (that would be flip subtract 10 which
would just be (10 -)

 I think you should have to write negative numbers using the syntax
 0-10, since currently having one single unary operator is ugly.

I think writing 0-10 is ugly.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Neil Mitchell
Hi

  I think you should have to write negative numbers using the syntax
  0-10, since currently having one single unary operator is ugly.

 I think writing 0-10 is ugly.

Ugly - yes. But very clear as to its meaning. How often do people
actually write negative numeric literals? My guess is that -1 is the
most common by a long way, but even that is quite rare. Of course,
real statistics of real programs are the only answer.

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Michael Campbell
On 10/16/07, Neil Mitchell [EMAIL PROTECTED] wrote:

 Ugly - yes. But very clear as to its meaning. How often do people
 actually write negative numeric literals?

Any time I need one.  And I can guarantee I don't make the compiler
perform an arithmetic computation to get one, either.



-- 
Wise men talk because they have something to say; fools, because they
have to say something. -- Plato
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread David Christensen

I think you should have to write negative numbers using the syntax
0-10, since currently having one single unary operator is ugly.


I think writing 0-10 is ugly.


Ugly - yes. But very clear as to its meaning. How often do people
actually write negative numeric literals? My guess is that -1 is the
most common by a long way, but even that is quite rare. Of course,
real statistics of real programs are the only answer.


If you were doing away with unary minus, I'd prefer going for it  
entirely and going for negate :: (Num a) = a - a.  It could also be  
compile-time folded, so no performance impact obviously.


It also expresses intent without looking as ugly:

minusTen:: negate 10

David


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Peter Verswyvelen
Concurrent Clean uses the ~ symbol for unary negation. That's also a way 
of fixing it.


Personally I could also live with allowing no space between the minus 
sign and the number... If you leave a space, - becomes the subtract 
operator.


Coming from C++ I always make the mistake to forget parentheses around 
negative numbers in Haskell, which is very often needed.


Neil Mitchell wrote:

Hi

  

I think you should have to write negative numbers using the syntax
0-10, since currently having one single unary operator is ugly.
  

I think writing 0-10 is ugly.



Ugly - yes. But very clear as to its meaning. How often do people
actually write negative numeric literals? My guess is that -1 is the
most common by a long way, but even that is quite rare. Of course,
real statistics of real programs are the only answer.

Thanks

Neil


  


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Isaac Dupree

Peter Verswyvelen wrote:
Personally I could also live with allowing no space between the minus 
sign and the number... If you leave a space, - becomes the subtract 
operator.


I once thought that... there was the opposition that (x-1) subtraction 
of a constant appears too often.  And I found that I myself wrote that 
several times.  And saying whitespace on the left but not the right 
seems too complicated for Haskell lexer semantics.  So the current 
situation is just unhappy, that's all. (and maybe compiler warnings 
could still be implemented)


Isaac
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread John Meacham
On Tue, Oct 16, 2007 at 06:27:19PM -0300, Isaac Dupree wrote:
 Peter Verswyvelen wrote:
 Personally I could also live with allowing no space between the minus 
 sign and the number... If you leave a space, - becomes the subtract 
 operator.
 
 I once thought that... there was the opposition that (x-1) subtraction 
 of a constant appears too often.  And I found that I myself wrote that 
 several times.  And saying whitespace on the left but not the right 
 seems too complicated for Haskell lexer semantics.  So the current 
 situation is just unhappy, that's all. (and maybe compiler warnings 
 could still be implemented)

not just unhappy, but inefficient. 
-10 tranlates to (negate (fromInteger 10)) requiring 2 indirect class
calls rather than what one might expect (fromInteger -10)

also, negate in Num is sort of ugly IMHO. It would be nice if it wern't
there. Things like naturals have a perfectly reasonable subtract, but no
negate.

I think losing x-1 would be worth it. but I know there were some other
ideas out there that might be preferable but could still be handled at
the lexing stage rather than the parsing one...  

John


-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior

2007-10-16 Thread Lennart Augustsson
If naturals have a perfectly reasonable subtraction then they also have a
perfectly reasonable negate; the default is 0-x.

(Oh, subtraction wasn't THAT reasonable, you say. :) )

  -- Lennart


On 10/17/07, John Meacham [EMAIL PROTECTED] wrote:

 On Tue, Oct 16, 2007 at 06:27:19PM -0300, Isaac Dupree wrote:
  Peter Verswyvelen wrote:
  Personally I could also live with allowing no space between the minus
  sign and the number... If you leave a space, - becomes the subtract
  operator.
 
  I once thought that... there was the opposition that (x-1) subtraction
  of a constant appears too often.  And I found that I myself wrote that
  several times.  And saying whitespace on the left but not the right
  seems too complicated for Haskell lexer semantics.  So the current
  situation is just unhappy, that's all. (and maybe compiler warnings
  could still be implemented)

 not just unhappy, but inefficient.
 -10 tranlates to (negate (fromInteger 10)) requiring 2 indirect class
 calls rather than what one might expect (fromInteger -10)

 also, negate in Num is sort of ugly IMHO. It would be nice if it wern't
 there. Things like naturals have a perfectly reasonable subtract, but no
 negate.

 I think losing x-1 would be worth it. but I know there were some other
 ideas out there that might be preferable but could still be handled at
 the lexing stage rather than the parsing one...

 John


 --
 John Meacham - ⑆repetae.net⑆john⑈
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Strange subtract operator behavior - and lazy naturals

2007-10-16 Thread John Meacham
On Wed, Oct 17, 2007 at 03:13:23AM +0100, Lennart Augustsson wrote:
 If naturals have a perfectly reasonable subtraction then they also have a
 perfectly reasonable negate; the default is 0-x.
 
 (Oh, subtraction wasn't THAT reasonable, you say. :) )


I suppose I was overextending the use of 'perfectly reasonable' here. :)

tangent:

if anyone is interested, Although I bet this has been implemented a
hundred times over, I have attached my lazy naturals module below just
for larks. It is quite efficient as such things go and very lazy. for
instance (genericLength xs  5) will only evaluate up to the 5th element
of the list before returning a result. and ((1 `div` 0)  17) is true,
not bottom.

Anyone have any comments on my lazy multiplication algorithm? since each
number is of the form (x + rx) (an integer, plus the lazy remainder) I
just did the multiplicitive expansion 

(x + rx) * (y + ry) - x*y + x*ry + y*rx + rx*ry
then I simplify to 
(x + rx) * (y + ry) - x*y + x*ry + rx*(y + ry)
which saves a nice recursive call to * speeding thinsg up signifigantly.
but is there a better way?

since (+) is lazy, we can still get a good lazy result without
evaluating the tails when multiplying... that is nice.

also, what do you think 
n `mod` 0 should be? I can see arguments for it being 'n', 0, or
Infinity depending on how you look at it.. hmm..


If anyone wants me to clean this up and package it as a real module, I
would be happy to do so.

sorry for the tangent. just one of those days.

John


-- 
John Meacham - ⑆repetae.net⑆john⑈

-- Copyright (c) 2007 John Meacham (john at repetae dot net)
-- 
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the
-- Software), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, sublicense, and/or sell copies of the Software, and to
-- permit persons to whom the Software is furnished to do so, subject to
-- the following conditions:
-- 
-- The above copyright notice and this permission notice shall be included
-- in all copies or substantial portions of the Software.
-- 
-- THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

-- efficient lazy naturals

module Util.LazyNum where

-- Nat data type is eqivalant to a type restricted lazy list that is strict in
-- its elements.
--
-- Invarients: (Sum x _) = x  0
-- in particular (Sum 0 _) is _not_ valid and must not occur.

data Nat = Sum !Integer Nat | Zero
deriving(Show)

instance Eq Nat where
Zero == Zero = True
Zero == _ = False
_ == Zero = False
Sum x nx == Sum y ny = case compare x y of
EQ - nx == ny
LT - nx == Sum (y - x) ny
GT - Sum (x - y) nx == ny


instance Ord Nat where
Zero = _ = True
_ = Zero = False
Sum x nx = Sum y ny = case compare x y of
EQ - nx = ny
LT - nx = Sum (y - x) ny
GT - Sum (x - y) nx = ny

Zero `compare` Zero = EQ
Zero `compare` _ = LT
_`compare` Zero = GT
Sum x nx `compare` Sum y ny = case compare x y of
EQ - nx `compare` ny
LT - nx `compare` Sum (y - x) ny
GT - Sum (x - y) nx `compare` ny

x  y = not (x = y)
x = y = y = x
x  y = y  x


instance Num Nat where
Zero + y = y
x + Zero = x
Sum x n1 + Sum y n2 = Sum (x + y) (n1 + n2)

Zero - _ = zero
x - Zero = x
Sum x n1 - Sum y n2 = case compare x y of
GT - Sum (x - y) n1 - n2
EQ - n1 - n2
LT - n1 - Sum (y - x) n2
negate _ = zero
abs x = x
signum Zero = zero
signum _ = one
fromInteger x = if x = 0 then zero else Sum x Zero

Zero * _ = Zero
_ * Zero = Zero
(Sum x nx) * (Sum y ny) = Sum (x*y) ((f x ny) + (nx * (fint y + ny))) where
f y Zero = Zero
f y (Sum x n) = Sum (x*y) (f y n)



instance Real Nat where
toRational n = toRational (toInteger n)

instance Enum Nat where
succ x = Sum 1 x
pred Zero = Zero
pred (Sum n x) = if n == 1 then x else Sum (n - 1) x
enumFrom x = x:[ Sum n x | n - [1 ..]]
enumFromThen x y = x:y:f (y + z) where
z = y - x
f x = x:f (x + z)
toEnum = fromIntegral
fromEnum = fromIntegral

-- d  0
doDiv :: Nat - Integer - Nat
doDiv n d = f 0 n where
f _ Zero = 0
f cm (Sum x nx) = sum d (f m nx) where
(d,m) = (x + cm) `quotRem` d
sum 0 x = x
sum n x = Sum n x

doMod :: Nat - Integer - Nat
doMod n d = f 0 n where
f 0 Zero = Zero
f r