2009-11-19 20 views
5

Estoy tratando de implementar una secuencia diferida (lo que significa que el siguiente elemento solo se calcula al invocar la función de paso), y uno de los métodos que debería tener es "mapa" que recibe una función que afecta a todos los miembros. La manera más elegante de hacer esto es usar la composición de funciones y asignar la nueva función a la variable de función, pero como las funciones no son valores de primera clase en Java, no tengo idea de cómo hacerlo.Composición de funciones en Java

Pensé en tener una clase que solo contenga una función, como una especie de contenedor de "función puntero", pero no veo cómo se puede usar para la composición.

Editar: pregunta es tarea relacionada. Además, debería ser capaz de manejar múltiples composiciones a lo largo de las líneas del mapa (map (map (stepFunction()))) ("map" en este caso es la función dada a través del método "map").

+0

Entonces, cuando dice que quiere hacer un mapa (mapa (mapa (stepFunction()))), ¿eso significa que tiene una lista de listas y desea llamar a stepFunction en cada elemento de todas las listas de niños en esa jerarquía? Todavía no estoy del todo claro sobre lo que estás tratando de lograr. –

+0

No. Básicamente este es el trato: solo tengo tres cosas en un momento dado: la función de paso, el valor actual y el valor base. Si Seq.map (someFunctionToMapWith) nunca se aplicó, entonces current value = base value = stepFunction (valor base anterior). Sin embargo, una vez que se aplica el mapa a la secuencia, cada vez que invoco a seq.tail() para cambiar el valor actual, primero cambio el valor base y lo mudo más usando la función que se me dio: curr = mapFunc (stepFunc (valor base))) (el valor base también se actualiza). Si el mapa fue invocado varias veces, debe ser un mapa (mapa (.. map (stepFunc (base value)) ..)). – EpsilonVector

Respuesta

5

Bienvenido a Java y su trabajo.

interface Function<T> { 
    public T eval(T argument); 
} 

class Lazy<T> { 
    private Iterator<T> source; 
    private Function<T> filter; 
    Lazy(final Iterator<t> source, final Function<T> filter) { 
     this.source = source; 
     this.filter = filter; 
    } 
    public T step() { 
     return filter.eval(source.next()); 
    } 
} 
+0

No veo cómo esto me ayuda con la composición. Quizás debería haber mencionado que debería ser capaz de responder a múltiples aplicaciones de map(). El comportamiento que quiero lograr es map (map (map (stepFunction()))) (por ejemplo). – EpsilonVector

+0

Luego haga Lazy extiéndase Iterator ... ¡La idea era darle un puntero en la dirección correcta, no escribir todo su código! –

+0

@EpsilonVector considere hacerlo una interfaz fluida, así que: 'stepFunction(). Map (Functor) .map (Functor) .take (5)' o lo que sea –

1

En Java, siempre lo hace con un protocolo de clase. Consulte java.lang.Thread y la función de ejecución para el ejemplo canónico. No hay 'punteros de función' o 'variables de función' en Java.

-1
public static <T> void apply(final List<T> list, final Function<T> func) 
{ 
    for(final T val : list) 
    { 
     func.perform(val); 
    } 
} 

interface Function<T> 
{ 
    void apply(T value); 
} 

class DisplayFunction<T> 
    implements Function<T> 
{ 
    public void perform(T value) 
    { 
     System.out.println(value); 
    } 
} 

la llamada se aplica (lista, nueva función de pantalla());

+0

y aparentemente al azar, sin ninguna razón para dar todavía. Si crees que algo anda mal, es cortés explicar por qué piensas eso. – TofuBeer

+0

Podría ser porque no responde la pregunta, que pregunta cómo componer dos funciones, no solo hacer mapas usando una. Además, las funciones en realidad no modifican sus entradas, devuelven un valor transformado por separado. –

+0

Puede cambiarlo a estático público R aplicar (lista final lista, función final func) para que devuelva un valor diferente (o elimine R y use T para el valor devuelto si el valor devuelto será el mismo).En general, no responderé la tarea directamente ... pero esta respuesta debería ser suficiente para comenzar. – TofuBeer

5

Google Collections tiene el tipo Function, el método Functions.compose(Function, Function), el método Iterables.transform(Iterable, Function), y mucho más.

No es útil para usted si esto es para la tarea (realmente me gustaría que todos revelaran si su pregunta está relacionada con la tarea).

+0

Está relacionado con tareas. – EpsilonVector

0

FWIW, el equivalente "puntero de función" en Java es una interfaz con un único método. Implementa la interfaz con alguna clase, que proporciona una implementación del método, y luego almacena una referencia a ese objeto de clase.

Cambiar la referencia a otro objeto de clase, que implementa el método de manera diferente, es equivalente a cambiar el puntero de función para apuntar a una función diferente.

Cuestiones relacionadas