As we've seen, Hope functions possess `full rights' and can be passed as actual parameters like any data object. It'll be no surprise to learn that we can return a function as the result of another function. The result can be a named function or an anonymous function defined by a lambda-expression. Here's a simple example:
dec makestep : num -> ( num -> num ) ; --- makestep ( i ) <= lambda ( x ) => i + x ;
makestep ( 3 ) ; lambda ( x ) => 3 + x : num -> numAs we can see from trying makestep, its result is an anonymous function that adds a fixed quantity to its single argument. The size of the increment was specified as an actual parameter to makestep when the new function was created, and has become `bound in' to its definition. If we try the new function, we'll see that it really does add 3 to its actual parameter:
makestep ( 3 ) ( 10 ) ; 13 : numThere are two applications here. First we apply makestep to 3, then the resulting anonymous function is applied to 10. Finally, here's a function that has functions as both actual parameter and result:
dec twice : ( alpha -> alpha ) -> ( alpha -> alpha ) ; --- twice ( f ) <= lambda ( x ) => f ( f ( x ) ) ;twice defines a new function that has a single argument and some other function f bound into its definition. The new function has the same type as f. We can see its effect using a simple function like square:
twice ( square ) ; lambda ( x ) => square( square ( x ) ) : num -> num
twice ( square ) ( 3 ) ; 81 : numThe new function applies the bound-in function to its argument twice. We can even bind in twice itself, generating a new function that behaves like twice except that the function eventually bound in will be applied four times:
twice ( twice ) ; lambda ( x ) => twice ( twice ( x ) ) : ( alpha -> alpha ) -> ( alpha -> alpha )
twice ( twice ) ( square ) ( 3 ) ; 43046721 : num