source: Dev/trunk/src/client/dojox/lang/functional/curry.js @ 483

Last change on this file since 483 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 3.0 KB
Line 
1dojo.provide("dojox.lang.functional.curry");
2
3dojo.require("dojox.lang.functional.lambda");
4
5// This module adds high-level functions and related constructs:
6//      - currying and partial functions
7//      - argument pre-processing: mixer and flip
8
9// Acknowledgements:
10//      - partial() is based on work by Oliver Steele
11//              (http://osteele.com/sources/javascript/functional/functional.js)
12//              which was published under MIT License
13
14// Defined methods:
15//      - take any valid lambda argument as the functional argument
16
17(function(){
18        var df = dojox.lang.functional, ap = Array.prototype;
19
20        var currying = function(/*Object*/ info){
21                return function(){      // Function
22                        var args = info.args.concat(ap.slice.call(arguments, 0));
23                        if(arguments.length + info.args.length < info.arity){
24                                return currying({func: info.func, arity: info.arity, args: args});
25                        }
26                        return info.func.apply(this, args);
27                };
28        };
29
30        dojo.mixin(df, {
31                // currying and partial functions
32                curry: function(/*Function|String|Array*/ f, /*Number?*/ arity){
33                        // summary:
34                        //              curries a function until the arity is satisfied, at
35                        //              which point it returns the calculated value.
36                        f = df.lambda(f);
37                        arity = typeof arity == "number" ? arity : f.length;
38                        return currying({func: f, arity: arity, args: []});     // Function
39                },
40                arg: {},        // marker for missing arguments
41                partial: function(/*Function|String|Array*/ f){
42                        // summary:
43                        //              creates a function where some arguments are bound, and
44                        //              some arguments (marked as dojox.lang.functional.arg) are will be
45                        //              accepted by the final function in the order they are encountered.
46                        // description:
47                        //              This method is used to produce partially bound
48                        //              functions. If you want to change the order of arguments, use
49                        //              dojox.lang.functional.mixer() or dojox.lang.functional.flip().
50                        var a = arguments, l = a.length, args = new Array(l - 1), p = [], i = 1, t;
51                        f = df.lambda(f);
52                        for(; i < l; ++i){
53                                t = a[i];
54                                args[i - 1] = t;
55                                if(t === df.arg){
56                                        p.push(i - 1);
57                                }
58                        }
59                        return function(){      // Function
60                                var t = ap.slice.call(args, 0), // clone the array
61                                        i = 0, l = p.length;
62                                for(; i < l; ++i){
63                                        t[p[i]] = arguments[i];
64                                }
65                                return f.apply(this, t);
66                        };
67                },
68                // argument pre-processing
69                mixer: function(/*Function|String|Array*/ f, /*Array*/ mix){
70                        // summary:
71                        //              changes the order of arguments using an array of
72                        //              numbers mix --- i-th argument comes from mix[i]-th place
73                        //              of supplied arguments.
74                        f = df.lambda(f);
75                        return function(){      // Function
76                                var t = new Array(mix.length), i = 0, l = mix.length;
77                                for(; i < l; ++i){
78                                        t[i] = arguments[mix[i]];
79                                }
80                                return f.apply(this, t);
81                        };
82                },
83                flip: function(/*Function|String|Array*/ f){
84                        // summary:
85                        //              changes the order of arguments by reversing their
86                        //              order.
87                        f = df.lambda(f);
88                        return function(){      // Function
89                                // reverse arguments
90                                var a = arguments, l = a.length - 1, t = new Array(l + 1), i = 0;
91                                for(; i <= l; ++i){
92                                        t[l - i] = a[i];
93                                }
94                                return f.apply(this, t);
95                        };
96                }
97        });
98})();
Note: See TracBrowser for help on using the repository browser.