KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jga > fn > BinaryFunctor


1 // ============================================================================
2
// $Id: BinaryFunctor.java,v 1.18 2006/11/30 05:03:42 davidahall Exp $
3
// Copyright (c) 2002-2005 David A. Hall
4
// ============================================================================
5
// The contents of this file are subject to the Common Development and
6
// Distribution License (CDDL), Version 1.0 (the License); you may not use this
7
// file except in compliance with the License. You should have received a copy
8
// of the the License along with this file: if not, a copy of the License is
9
// available from Sun Microsystems, Inc.
10
//
11
// http://www.sun.com/cddl/cddl.html
12
//
13
// From time to time, the license steward (initially Sun Microsystems, Inc.) may
14
// publish revised and/or new versions of the License. You may not use,
15
// distribute, or otherwise make this file available under subsequent versions
16
// of the License.
17
//
18
// Alternatively, the contents of this file may be used under the terms of the
19
// GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
20
// case the provisions of the LGPL are applicable instead of those above. If you
21
// wish to allow use of your version of this file only under the terms of the
22
// LGPL, and not to allow others to use your version of this file under the
23
// terms of the CDDL, indicate your decision by deleting the provisions above
24
// and replace them with the notice and other provisions required by the LGPL.
25
// If you do not delete the provisions above, a recipient may use your version
26
// of this file under the terms of either the CDDL or the LGPL.
27
//
28
// This library is distributed in the hope that it will be useful,
29
// but WITHOUT ANY WARRANTY; without even the implied warranty of
30
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
// ============================================================================
32

33 package net.sf.jga.fn;
34
35 import java.io.Serializable JavaDoc;
36 import net.sf.jga.fn.adaptor.Bind1st;
37 import net.sf.jga.fn.adaptor.Bind2nd;
38 import net.sf.jga.fn.adaptor.ChainBinary;
39 import net.sf.jga.fn.adaptor.ComposeBinary;
40 import net.sf.jga.fn.adaptor.ComposeUnary;
41 import net.sf.jga.fn.adaptor.Distribute;
42 import net.sf.jga.fn.adaptor.Generate1st;
43 import net.sf.jga.fn.adaptor.Generate2nd;
44 import net.sf.jga.fn.adaptor.Identity;
45
46 /**
47  * A Function Object that takes two arguments and returns a result. The two
48  * arguments are of type <code>T1</code> and <code>T2</code>, and
49  * the result is of type <code>R</code>
50  * <p>
51  * Copyright &copy; 2002-2005 David A. Hall
52  *
53  * @author <a HREF="mailto:davidahall@users.sourceforge.net">David A. Hall</a>
54  **/

55
56 abstract public class BinaryFunctor<T1,T2,R> extends Functor<R> implements Serializable JavaDoc,Visitable {
57     /**
58      * Executes the function and returns the result.
59      */

60     abstract public R fn(T1 arg1, T2 arg2);
61
62     /**
63      * Factory method that creates a UnaryFunctor that binds a constant value to
64      * this' first argument. Given argument <b>x</b>, the new functor will
65      * return <code>fn<sub>this</sub>(value, x)</code>
66      */

67     public UnaryFunctor<T2,R> bind1st (T1 value){
68         return new Bind1st<T1,T2,R>(value, this);
69     }
70
71     /**
72      * Factory method that creates a UnaryFunctor that binds a constant value to
73      * this' second argument. Given argument <b>x</b>, the new functor will
74      * return <code>fn<sub>this</sub>(x, value)</code>
75      */

76     public UnaryFunctor<T1,R> bind2nd (T2 value){
77         return new Bind2nd<T1,T2,R>(value, this);
78     }
79
80     /**
81      * Factory method that creates a Generator that binds constant values to
82      * this' arguments. The new generator will return
83      * <code>fn<sub>this</sub>(value1, value2)</code>
84      */

85     public Generator<R> bind (T1 value1, T2 value2) {
86         return bind1st(value1).bind(value2);
87     }
88
89     /**
90      * FactoryMethod that creates a UnaryFunctor that passes its argument to
91      * each of the given functors, and uses the results as the arguments to this
92      * function. Given argument <b>x</b>, the new functor will return
93      * <code>fn<sub>this</sub>(g(x), h(x))</code>
94      */

95     public <F> UnaryFunctor<F,R> compose (UnaryFunctor<F,T1> g, UnaryFunctor<F,T2> h) {
96         return new ComposeUnary<F,T1,T2,R>(g,h,this);
97     }
98
99     /**
100      * FactoryMethod that creates a BinaryFunctor that passes its argument to
101      * each of the given functors, and uses the results as the arguments to this
102      * function. Given arguments <b>x</b> and <b>y</b>, the new functor will
103      * return <code>fn<sub>this</sub>(g(x,y), h(x,y))</code>
104      */

105     public <F1,F2> BinaryFunctor<F1,F2,R>
106     compose (BinaryFunctor<F1,F2,T1> g, BinaryFunctor<F1,F2,T2> h)
107     {
108         return new ComposeBinary<F1,F2,T1,T2,R>(g,h,this);
109     }
110
111     /**
112      * FactoryMethod that creates a BinaryFunctor that passes each of its two
113      * arguments to a pair of UnaryFunctors, then uses the results as arguments
114      * to this function. Given arguments <b>x</b> and <b>y</b>, the new functor
115      * will return <code>fn<sub>this</sub>(g(x), h(y))</code>. Note: this
116      * method cannot be called compose, as it is only distinct from the unary
117      * form of compose in its param types and its return type
118      */

119     public <F1,F2> BinaryFunctor<F1,F2,R> distribute (UnaryFunctor<F1,T1> g, UnaryFunctor<F2,T2> h)
120     {
121         return new Distribute<F1,F2,T1,T2,R>(g,h,this);
122     }
123
124     /**
125      * FactoryMethod that converts this functor to a UnaryFunctor by using the
126      * given generator to produce the first argument. Given argument <b>y</b>,
127      * the new functor will return <code>fn<sub>this</sub>(gen(), y)</code>.
128      */

129     
130     public UnaryFunctor<T2,R> generate1st(Generator<T1> gen) {
131         return new Generate1st<T1,T2,R>(this, gen);
132     }
133
134     /**
135      * FactoryMethod that converts this functor to a UnaryFunctor by using the
136      * given generator to produce the first argument. Given argument <b>x</b>,
137      * the new functor will return <code>fn<sub>this</sub>(x, gen())</code>.
138      */

139     
140     public UnaryFunctor<T1,R> generate2nd(Generator<T2> gen) {
141         return new Generate2nd<T1,T2,R>(this, gen);
142     }
143
144     /**
145      * FactoryMethod that converts this functor to a Generator by using the two
146      * given generators to produce the arguments. The new functor will return
147      * <code>fn<sub>this</sub>(gen1(), gen2())</code>.
148      */

149     
150     public Generator<R> generate(Generator<T1> gen1, Generator<T2> gen2) {
151         return generate1st(gen1).generate(gen2);
152     }
153
154     // -----------------
155
// Functor interface
156
// -----------------
157

158     public R eval(Object JavaDoc... args) {
159         // @SuppressWarnings
160
// This generates two unchecked cast warnings: we're crossing the line from
161
// unsafe rawform code to typesafe generic code. This interface is known
162
// to be unsafe, and documented to the user as such.
163
return fn((T1) args[0], (T2)args[1]);
164     }
165
166     // -------------------
167
// Visitable interface
168
// -------------------
169

170     /**
171      * No-op implementation of Visitable interface.
172      */

173     public void accept(Visitor v) {}
174 }
175
Popular Tags