¿Son los métodos encadenados que requieren solo un parámetro por método equivalente al curry?

15

Últimamente he estado jugando con Ruby y me pregunté si en lenguajes orientados a objetos puros (e incluso en aquellos que no son puros) hacer métodos que solo toman un parámetro y luego se encadenan es equivalente a cursar en lenguajes con un lenguaje funcional. ¿estilo? ¿Si no, porque no? Agradecería una respuesta detallada, incluso rigurosa sobre el tema.

Ingeniero mundial
fuente

Respuestas:

14

El encadenamiento de métodos en lenguajes orientados a objetos es un poco diferente al curry. Por definición , el resultado del currículum es una forma más restringida de la función original . Por convención , el resultado de encadenamiento método es una forma modificada del original (normalmente de no funcionamiento) objeto . El encadenamiento de métodos se puede usar con métodos no relacionados en la misma clase, mientras que el currículum implica devolver una función donde uno o más parámetros de la función original son fijos (predeterminados).

En Java, el encadenamiento de métodos es como:

String myString = new StringBuilder("Hi ").append(firstName)
                                          .append(" ")
                                          .append(lastName)
                                          .append("!")
                                          .toString();

Entonces, cada una de esas llamadas al método .append () devuelve un puntero al objeto anónimo StringBuilder. Este objeto se completa después de cada .append (), y no es una función.

Por el contrario, en Scala, la aplicación parcial o el curry es como:

def simple(x:Int, y:Int, z:Int) = x * (y + z)
val simpler = simple(2, _:Int, _:Int)
simpler(3, 4) => 14

(Muestra tomada del blog de Daniel Yankowsky )

simpler()en este ejemplo es una función de envoltura para simple(). simpler()sigue siendo una función que toma más parámetros antes de poder evaluar cualquier cosa que no sea una versión más limitada de sí misma.

EDITAR: Leyendo esto un día después, creo que la "función de envoltura" es la clave. El currículum o la aplicación parcial pueden simularse mejor en Java con métodos de envoltura.

public interface Simpler {
    public int apply(int y, int z);
}

public class Simple {
    public int apply(int x, int y, int z) { return x * (y + z); }

    public Simpler partiallyApply(final int x) {
        final simple = this;
        return new Simpler() {
            @Override
            public int apply(int y, int z) {
                // x is the final int parameter to partiallyApply()
                simple.apply(x, y, z);
            }
        }
    }
}

: EDICIÓN FINAL

El encadenamiento de métodos puede ser similar a la aplicación parcial o al currículum, pero solo puede ser equivalente a los métodos que devuelven otros métodos (buscar Functores), y luego los métodos deben configurarse con tipos de retorno que modelen significativamente el currículum o la aplicación parcial.

El encadenamiento de métodos se usa con mayor frecuencia para implementar algo como la evaluación diferida, como se hace con el patrón de diseño "Generador" y las nuevas interfaces de la Biblioteca de colecciones en Java 8 .

Espero que eso ayude.

GlenPeterson
fuente
+1: Lo sabía, pero no creo que pudiera haberlo articulado tan cerca como tú.
Peter Rowell
Bien explicado, aquí hay una marca de verificación verde y un voto positivo por sus problemas.
Ingeniero mundial
Pregunta sobre el muy buen ejemplo de StringBuilder: sin la toString()llamada, ¿no estamos replicando efectivamente la intención de curry en nuestra llamada? Solo estoy tratando de entender el concepto de curry en OO.
Sridhar Sarnobat
1
@ Sridhar-Sarnobat una función curry devuelve otra función con menos parámetros. Los parámetros eliminados se convierten en constantes internas en la función devuelta. Algunos objetos se tratan como funciones en Java 8, lo que puede hacer que esto sea confuso, pero StringBuilder no es uno de ellos. Hmm, dentro de StringBuilder, la append(charSeq)función es una forma curricular de la insert(destOffset, charSeq)función donde destOffsetsiempre es la longitud de StringBuilder.
GlenPeterson