Skip to content

Commit 8fbad39

Browse files
committed
Revert "Quitando ejemplos no mostrados en clase"
This reverts commit f1a0005.
1 parent d78b609 commit 8fbad39

3 files changed

Lines changed: 467 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.platzi.functional._12_currying;
2+
3+
import java.util.function.Function;
4+
5+
public class Currying {
6+
/**
7+
* Empecemos con algo que ya conocemos: una FunctionalInterface que toma 3 tipos de datos
8+
* F, S, T y devuelve un tipo de dato R cuando se manda a llamar su metodo apply.
9+
* <p>
10+
* Hasta que no deberia haber nada nuevo.
11+
*/
12+
@FunctionalInterface
13+
interface ThreeFunction<F, S, T, R> {
14+
R apply(F f, S s, T t);
15+
}
16+
17+
static void curryingExample() {
18+
/*
19+
Tener tres parametros puede hacer que nos confundamos en el orden mientras programamos.
20+
Y tenemos un detalle, tal vez, por alguna razon, al momento de querer ejecutar esta funcion
21+
no contamos con los 3 datos.
22+
*/
23+
ThreeFunction<Integer, String, Double, String> threeFunction = (i, s, d) -> "";
24+
threeFunction.apply(1, "", 0.0);
25+
26+
/*
27+
Que tal si pudieramos simplificar nuestra funcion?
28+
29+
A reducir la complejidad de una funcion partiendola en subfunciones, se le conoce como currying.
30+
31+
Currying es una manera de crear funciones mas dinamicas basados en al reduccion de parametros.
32+
*/
33+
Function<Integer, Function<String, Function<Double, String>>> curried = curryThree(threeFunction);
34+
35+
curried.apply(1)
36+
.apply("")
37+
.apply(0.0);
38+
}
39+
40+
/**
41+
* Esta funcion, se encarga de tomar una funcion compleja de 3 parametros y simplificarla a una funcion de un
42+
* solo parametro.
43+
* <p>
44+
* Desafortunadamente, los generics de java complican un poco su lectura. pero es relativamente sencillo entender
45+
* lo que pasa:
46+
* <p>
47+
* curryThree toma una funcion de tres parametros ThreeFunction<F,S,T,R> y genera una version mas "simple".
48+
*
49+
* Esa version "simple" es una funcion que retorna otra funcion que retorna otra funcion.
50+
*
51+
* Es decir, tendremos 3 funciones que se pueden encadenar y generar el mismo resultado o ir ejecutando
52+
* una funcion a la vez conservando un estado anterior.
53+
*
54+
* El beneficio es que ahora tenemos una funcion mas simple de un solo parametro y que podemos reutilizar
55+
* para generar funciones "intermedias".
56+
*/
57+
static <F, S, T, R> Function<F, Function<S, Function<T, R>>> curryThree(ThreeFunction<F, S, T, R> threeFunction) {
58+
return first ->
59+
second ->
60+
third -> threeFunction.apply(first, second, third);
61+
}
62+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package com.platzi.functional._13_partial_application;
2+
3+
import java.util.function.BiFunction;
4+
import java.util.function.Function;
5+
6+
public class Partial {
7+
8+
static void partialApplication() {
9+
/*
10+
Usando currying podemos hacer uso de otra estrategia que se conoce como aplicacion parcial.
11+
12+
Hacer uso de la aplicacion parcial es almacenar la version "curried" de una funcion pero
13+
con un parametro.
14+
15+
Tomemos una BiFunction por ejemplo:
16+
*/
17+
BiFunction<Integer, Integer, Integer> multiplyXbyY = (x, y) -> x * y;
18+
19+
//Es facil usarla:
20+
System.out.println(
21+
multiplyXbyY.apply(5, 4) //20
22+
);
23+
24+
//Pero si quisieramos asignar un valor fijo a una funcion? Partial application al rescate.
25+
26+
/*
27+
Primero, definamos una funcion que hace currying:
28+
*/
29+
Function<BiFunction<Integer, Integer, Integer>, Function<Integer, Function<Integer, Integer>>>
30+
curryBiFunction = biFun -> X -> Y -> biFun.apply(X, Y);
31+
32+
/*
33+
Ahora podemos definir una funcion que genera mas funciones, usando la BiFunction que ya tenemos:
34+
*/
35+
Function<Integer, Function<Integer, Integer>> multiplyBy =
36+
x -> curryBiFunction.apply(multiplyXbyY).apply(x);
37+
38+
//Y crear funciones para valores especificos:
39+
Function<Integer, Integer> multiplyBy5 = y -> multiplyBy.apply(5).apply(y);
40+
41+
System.out.println(
42+
multiplyBy5.apply(20)
43+
);
44+
45+
Function<Integer, Integer> multiplyBy2 = x -> multiplyBy.apply(2).apply(x);
46+
47+
System.out.println(
48+
multiplyBy2.apply(10)
49+
);
50+
}
51+
52+
53+
//
54+
//
55+
//
56+
//
57+
//
58+
//
59+
//
60+
//
61+
//
62+
//
63+
//
64+
//
65+
//
66+
//
67+
//
68+
//
69+
//
70+
71+
/**
72+
* Aqui un ejemplo mas complejo:
73+
*/
74+
static void ejemploDB(DBConfiguration connectionConf) {
75+
//Imagina que tuvieramos esta funcion, que puede recibir una configuracion
76+
// de conexion a una base de datos y un query a ejecutar sobre dicha conexion.
77+
BiFunction<DBConfiguration, Query, QueryResult> biDB = (conf, query) ->
78+
new DataBaseConnection(conf).executeQuery(query);
79+
80+
//Por cada corrida sobre esa funcion, tendremos que pasar la configuracion
81+
QueryResult result1 = biDB.apply(connectionConf, new Query("SELECT …"));
82+
//Que aunque no esta mal, parece algo redundante…
83+
result1 = biDB.apply(connectionConf, new Query("INSERT …"));
84+
85+
//Podemos aplicar curry a nuestra bifunction para simplificar las llamadas:
86+
Function<DBConfiguration, Function<Query, QueryResult>> dbFunCreator = curryBiFunction(biDB);
87+
88+
//Creamos una funcion que trabajara sobre postgres…
89+
Function<Query, QueryResult> postgresExecutor =
90+
pgQuery -> dbFunCreator.apply(new DBConfiguration(/*Postgres configs*/)).apply(pgQuery);
91+
92+
//Y otra funcion para MariaDB
93+
Function<Query, QueryResult> mariaDBExecutor =
94+
query -> dbFunCreator.apply(connectionConf).apply(query);
95+
96+
postgresExecutor.apply(new Query("SELECT…"));
97+
postgresExecutor.apply(new Query("INSERT…"));
98+
99+
mariaDBExecutor.apply(new Query("UPDATE…"));
100+
}
101+
//
102+
//
103+
//
104+
//
105+
//
106+
//
107+
//
108+
//
109+
//
110+
//
111+
//
112+
//
113+
//
114+
//
115+
116+
static <F, S, R> Function<F, Function<S, R>> curryBiFunction(BiFunction<F, S, R> biFunction) {
117+
return f -> s -> biFunction.apply(f, s);
118+
}
119+
//
120+
//
121+
//
122+
//
123+
//
124+
//
125+
//
126+
//
127+
//
128+
//
129+
//
130+
//
131+
//
132+
//
133+
134+
static class QueryResult {
135+
136+
}
137+
138+
static class Query {
139+
public Query() {
140+
141+
}
142+
143+
public Query(String query) {
144+
}
145+
}
146+
147+
static class DBConfiguration {
148+
private String host;
149+
private String user;
150+
private String password;
151+
152+
private int port;
153+
154+
public DBConfiguration() {
155+
}
156+
157+
public DBConfiguration(String host, String user, String password, int port) {
158+
this.host = host;
159+
this.user = user;
160+
this.password = password;
161+
this.port = port;
162+
}
163+
}
164+
165+
static class DataBaseConnection {
166+
public DataBaseConnection(DBConfiguration dbConfiguration) {
167+
}
168+
169+
public QueryResult executeQuery(Query query) {
170+
return null;
171+
}
172+
}
173+
}

0 commit comments

Comments
 (0)