How to Write recursive lambda expressions

Source: Internet
Author: User

This question seems very simple, isn't it? Just write one:

 
Func<Int,Int>Factorial=X=>X=0?1: X*Factorial (x-1);

But this cannot be compiled, because you are defining factorial with factorial, the compiler will prompt that factorial is a variable not assigned a value:

Many people have suggested that this is not the case below?

 
Func<Int,Int>Factorial=Null; Factorial=X=>X=0?1: X*Factorial (x-1);

Smart, the problem seems to have been solved! However, if you do not change factorial, consider writing the following:Code:

 
VaRF2=Factorial; factorial=I=>I;Console.Writeline (F2 (5));

Guess the output result? Congratulations, 20. The reason is very simple. Because factorial = I => I, after F2 is expanded, it becomes:

X=>X=0?1: X*(I=>I) (x-1)

Thanks to the closure, this is not the factorial function we want! This method can be used in many cases, but avoid changing factorial. Now we are looking for a method that is not so error-prone.

 

Function ing function (the legendary High-Order Function ?)

Back to the first formula, we were faced with unknown numbers. Generally, when we don't know something, we set it to an unknown number, and then the equation is shown as a column. According to programming, we just turn it into a parameter, another way is to make other people better use it (the legendary IOC ?) :

 Func  <  Func <  Int  ,  Int  >  ,  Int  ,  Int  >  Factorial  =  (FAC, X)  =>  X  =  0  ?  1 : X  *  FAC (x  -  1  ); 

It looks good, but FP friends will think it is better:

 Func  <  Func  <  Int  ,  Int  >  ,  Func  <  Int ,  Int  >  Map  =  FAC  =>  X  =>  X  =  0  ?  1  : X  *  FAC (x  -  1 ); 

In this way, the relationship between two parameters of a function is no longer parallel, but a function. It takes a function as a parameter and returns another function. The other function takes a number, and capture the parameters (closures) received by the first function to do something. In other words,The parameters and returned values received by the map function are of the function type.That is, the legendary high-order function. In my understanding, it is to map a function to another function (I hope this description can be justified ).

This idea is crazy. Now we only need to let "people" tell us what we want, and we can get what we want by taking the map. Obviously, the problem is that this "family" is actually us.

 

This "family" is our (the so-called fixed point of the function ?)

High school mathematics: If a function f (x) has the points x = f (x), these points are called the fixed points of the function f (x. Of course, both the definition field and value field are real numbers. But what if the definition and value fields are both functions?

Let's look at the above map function. Suppose we find its fixed point factorial and throw it to the map function. Expand:

Map (factorial)=X=>X=0?1: X*Factorial (x-1)

According to the definition of fixed points, map (factorial) = factorial, substituted into the above formula, that is

Factorial=X=>X=0?1: X*Factorial (x-1)

Isn't that the formula we wrote at the beginning? So the conclusion is that if someone finds the fixed point of the map function, then we take it and throw it to the map function, then the function returned by it is the function we want!

Next we will look at the fixed point of the map function. Finding these points in the real number field can become very difficult (I would like to ask you how to find the fixed point of f (x) = (1/16) X, which is not an approximation. I am very grateful ), but looking for such a defined domain and value domain is a function, but there is a great man's shoulder to let us step on. This is an entertaining fixed point Combinator:

If you are interested, you can try it, but here we use a practical method to find it, that is, to write a method, receive the map function, and return its fixed point:

  static   func     T, T  >  fix     T  >  (  func     func     T, T  > ,  func     T, T  >>  map) {  //...  } 

In fact, The Fix (MAP) is the fixed point we are looking for:

  static   func     T, T  >  fix     T  >  (  func     func     T, T  > ,  func     T, T  >>  map) {  return   fix (MAP );}  

Are there any mistakes ?! In this way, we are in an endless loop!

Remember, we are looking for a fixed point, but we have no fixed point definition! So that f = fix (MAP), then f = map (f), that is, as mentioned earlier, MAP:

  static   func     T, T  >  fix     T  >  (  func     func     T, T  > ,  func     T, T  >>  map) {  return   map (fix (MAP ));}  

In this way, we recursively expand the fixed point of map, that is, the target function. So far, so good, isn' t it?

In fact, we only do this by recursively expanding the fixed point of a function, that is, it itself. This process is infinite. This means that someone needs a fixed point of a function, we have to wait for a long time before we can be the unlucky guy! In fact, as long as you know the specific input value, and this function can be stopped under this input value, this expansion can be stopped (of course, this is the case, I think this sentence is useless ......), Then we should return a function that knows the input value before expanding the target function:

 Static  Func  <  T, T  >  Fix  <  T  >  (  Func  <  Func <  T, T  >  ,  Func  <  T, T  >  Map ){  Return  X  =>  Map (fix (MAP) (x );} 

The description of this technique reminds me of jquery tutorials ......

 

Summary

After all, let's get the code ......

 Class  Program {  Static void  Main (  String  [] ARGs ){  Func  <  Func  <  Int  ,  Int  >  ,  Func  <  Int  , Int  >  Map  =  FAC  =>  X  =>  X  =  0  ?  1  : X  *  FAC (x  -  1 );  VaR  Factorial  =  Fix (MAP );  Console  .  Writeline (factorial (  5  ));  Console  .  Readkey ();}  Static  Func  <  T, T >  Fix  <  T  >  (  Func  <  Func  <  T, T  >  ,  Func  <  T, T  >  Map ){ Return  X  =>  Map (fix (MAP) (x );}} 

The definition of factorial can also be written as follows:

 
VaRFactorial=Map (fix (MAP ));

But it's not necessary ......

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.