package lab4;
/*
 * class Factorial
 * By Martin Robinson
 * return the factorial of a given number
 * */
public class Factorial {
	/*constructor*/
	private Factorial(){}

	/*functor*/
	private interface Fact{
		long val();
		long eval();
	}

	/*method*/
	private Fact _factorise(int n, final Fact last){
		//foncteur anonyme
		Fact result = new Fact(){
			private Fact next = last;
			public long val(){
				return next.val()+1;
			}
			public long eval(){
				return next.eval() * val();
			}
		};
		//appel recursif conditionnel
		if (n>1)
			return _factorise(n-1, result);
		return result;
	}

	//meta construit un objet immuable qui calcul recursivement
	//la factoriel de n
	public Fact factorise(int n){
		//functor anonyme
		Fact result = new Fact() {
			public long val(){
				return 1;
			}
			public long eval(){
				return 1;
			}
		};

		//appel recursive
		return _factorise(n-1,result);
	}

	/*main*/
	public static void main(String [] args){
		Factorial tmp = new Factorial();

		System.out.println("factorise 5");
		System.out.println("=" + tmp.factorise(5).eval());
	}
}
