Reputation: 1060
A class Nat represents a Number (n) by having pre field which points to the n-1 number, if pre is null it means the number is zero.
public class Nat {
private final Nat pre;
public Nat (Nat pre) { this.pre = pre; }
public Nat () { this(null); }
public boolean isZero () { return pre == null; }
public Nat succ () { return new Nat(this); }
…
}
and I have to add a method which adds two numbers, I dont understand how this suppose to return a Nat which represents the sum of "this" and other!
public Nat plus (Nat other) {
if (other.isZero())
return this;
return succ().plus(other.pre);
}
I think it creates a "Nats" which point to the second Nat of this (pre) all the time.. Could any one help me please?
Upvotes: 4
Views: 196
Reputation: 56626
This recursion is easier to understand in a functional language.
I am sure that other posts are clear enough for plus
(a+b
becomes a+1+b-1
).
What it has to be clear is related to this part:
public Nat (Nat pre) { this.pre = pre; }
...
public Nat succ () { return new Nat(this); }
When succ()
is called, it returns a new Object, so this
from here:
public Nat succ () { return new Nat(this); }
will be pre
from here:
public Nat (Nat pre) { this.pre = pre; }
This is why that succ
works because there will be something like this.pre.pre....pre
at the end.
To understand better, you can type this (eventually add some print lines in your methods):
public static void main(String[] args) {
System.out.println("==== A new number is 0 ====");
Nat n1 = new Nat(); // 0
System.out.println(n1.isZero()); // true
Nat n2 = new Nat(); // 0
System.out.println(n2.isZero()); // true
Nat sum = n1.plus(n2); // 0
System.out.println(sum.isZero()); // true
System.out.println(n2.isZero()); // true
System.out.println("==== Test succ and pre ====");
Nat one = n1.succ(); // 1
System.out.println(one.isZero()); // false
Nat two = one.plus(one); // 1 + 1
System.out.println(two.isZero()); // false
System.out.println(two.pre.isZero()); // false
System.out.println(two.pre.pre.isZero()); // true
}
Upvotes: 0
Reputation: 3562
Basically it unrolls the equation
n + k = (n + 1) + (k - 1)
Until k is zero. In the process a lot of temporary Nats are created but the final result is the Nat where the other Nat addend is zero: you kind of accumulates the result in the first Nat. Write down a simple execution of the algorithm with all the calls and you will see it.
Example: 1 + 2
1.plus(2)
-- 1.succ().plus(1)
---- 1.succ().succ().plus(0)
------> 1.succ().succ() == 3
EDIT: contrary to the other posts, I think this is not strictly speaking a recursive recursion. In fact the plus() method is not called always on the same object instance. The behavior is indeed recursive though. Then it depends on your definitions
Upvotes: 1
Reputation: 15141
You don't store the numbers directly in the list and create it recursively:
Why the plus() works:
Now we can observe that addition x+y
can be changed to (x-1)+(y+1)
etc. until 0 + (y + x)
. In your code you are not really interested in addition per se but you want to get to the Nat
which represents the result of the summation. You do that recursively by using the above transformation until other
is 0
- this is your base case which simply counts the recursive calls and makes sure you do them x
times.
Example:
[null -> Nat1(pre=null) -> Nat2(pre=Nat1) -> Nat3(pre=Nat2) -> Nat4(pre=Nat3) -> Nat5(pre=Nat5)]
And let's say you want to add 3
and 2
. First you start with other=Nat2
and call it on Nat3
, so you get Nat3's
successor which is Nat4
and call plus()
on it using other's
predecessor which is Nat1
, still no zero so you call plus()
on Nat4's
successor (Nat5
) with Nat1's
predecessor which is null
, you hit your base case and return this
which at this point of recursion is Nat5
.
Upvotes: 1
Reputation: 393781
Well, if this
represents n
and other
represents m
, to calculate n
+ m
is equivant to calculating n+1
+ m-1
, which is exactly what succ().plus(other.pre)
returns.
At the end of the recurssion, the first number reaches n+m
and the second number reaches 0
. That's why you return this
when other.isZero()
is true.
Upvotes: 4