source: Dev/branches/rest-dojo-ui/client/dojox/lang/functional/curry.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • 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// Acknoledgements:
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: curries a function until the arity is satisfied, at
34                        //      which point it returns the calculated value.
35                        f = df.lambda(f);
36                        arity = typeof arity == "number" ? arity : f.length;
37                        return currying({func: f, arity: arity, args: []});     // Function
38                },
39                arg: {},        // marker for missing arguments
40                partial: function(/*Function|String|Array*/ f){
41                        // summary: creates a function where some arguments are bound, and
42                        //      some arguments (marked as dojox.lang.functional.arg) are will be
43                        //      accepted by the final function in the order they are encountered.
44                        // description: This method is used to produce partially bound
45                        //      functions. If you want to change the order of arguments, use
46                        //      dojox.lang.functional.mixer() or dojox.lang.functional.flip().
47                        var a = arguments, l = a.length, args = new Array(l - 1), p = [], i = 1, t;
48                        f = df.lambda(f);
49                        for(; i < l; ++i){
50                                t = a[i];
51                                args[i - 1] = t;
52                                if(t === df.arg){
53                                        p.push(i - 1);
54                                }
55                        }
56                        return function(){      // Function
57                                var t = ap.slice.call(args, 0), // clone the array
58                                        i = 0, l = p.length;
59                                for(; i < l; ++i){
60                                        t[p[i]] = arguments[i];
61                                }
62                                return f.apply(this, t);
63                        };
64                },
65                // argument pre-processing
66                mixer: function(/*Function|String|Array*/ f, /*Array*/ mix){
67                        // summary: changes the order of arguments using an array of
68                        //      numbers mix --- i-th argument comes from mix[i]-th place
69                        //      of supplied arguments.
70                        f = df.lambda(f);
71                        return function(){      // Function
72                                var t = new Array(mix.length), i = 0, l = mix.length;
73                                for(; i < l; ++i){
74                                        t[i] = arguments[mix[i]];
75                                }
76                                return f.apply(this, t);
77                        };
78                },
79                flip: function(/*Function|String|Array*/ f){
80                        // summary: changes the order of arguments by reversing their
81                        //      order.
82                        f = df.lambda(f);
83                        return function(){      // Function
84                                // reverse arguments
85                                var a = arguments, l = a.length - 1, t = new Array(l + 1), i = 0;
86                                for(; i <= l; ++i){
87                                        t[l - i] = a[i];
88                                }
89                                return f.apply(this, t);
90                        };
91                }
92        });
93})();
Note: See TracBrowser for help on using the repository browser.