Created
May 11, 2019 14:33
-
-
Save javierfernandes/ebeab2842a2447a3e438f95c5d79001b to your computer and use it in GitHub Desktop.
O3 - FP - Pociones - En clase (2019-c1)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package ar.edu.unq.o3 | |
| object Hogwarts { | |
| // definiciones de tipos | |
| type Persona = (String, Niveles) | |
| type Niveles = (Int, Int, Int) | |
| type Efecto = Niveles => Niveles | |
| // permite acceder a los elementos de la tupla Niveles mediante un mensaje con nombre | |
| // en lugar de usar ._1, ._2 y ._3 | |
| implicit class NivelesWrapper(n: Niveles) { | |
| def suerte = n._1 | |
| def convencimiento = n._2 | |
| def fuerza = n._3 | |
| } | |
| def niveles(p: Persona): Niveles = p._2 | |
| } | |
| object Efectos { | |
| import ar.edu.unq.o3.Hogwarts._ | |
| // | |
| // primera versión de duplica y alMenos7 usando mapNiveles | |
| // | |
| def mapNiveles: (Int => Int) => Efecto = fn => n => { | |
| (fn(n._1), fn(n._2), fn(n._3)) | |
| } | |
| def duplicaV1 = mapNiveles(_ * 2) | |
| def alMenos7V1 = mapNiveles(_.max(7)) | |
| // | |
| // segunda versión usando composición de funciones (andThen) | |
| // claramente es mejor la primera versión. Lo hicimos como excusa para trabajar más con funciones | |
| // y probar la composición | |
| // | |
| // necesitamos funciones auxiliares | |
| def toList = (n: Niveles) => List(n._1, n._2, n._3) | |
| def fromList = (l: List[Int]) => (l(0), l(1), l(2)) | |
| // definimos el map() de listas de Int como una función de orden superior y aplicación parcial | |
| // usamos gruppos de parámetros para poder primero llamara con la operación de mapeo y luego que | |
| // otra función la aplique efectivamente con la lista. | |
| // En nuesto caso el andThen se va a encargar de aplicarle la lista, como parte de la composición | |
| // o "linea/pipeline" de ejecución del "duplica" | |
| def map(fn: (Int) => Int)(l:List[Int]) = l.map(fn) | |
| // | |
| // Esto se podría haber definido de otras formas sin usar "grupop de parametros" de scala | |
| // | |
| // map2: un solo grupo de parametros. El que la use la va a tener que aplicar parcialmente, así | |
| // toList.andThen(map2( a => a *2, _ )).andThen(fromList) | |
| def map2(fn: (Int) => Int, l: List[Int]) = l.map(fn) | |
| // map2: función de orden superior. El map ahora retorna una nueva función. Así que no hace falta | |
| // aplicarla parcialmente. Es una función "creadora" que crea otra función | |
| // esta la usaríamos así, igual que la "map" original | |
| // toList.andThen(map3(a => a * 2)).andThen(fromList) | |
| def map3(fn: (Int) => Int) = (l: List[Int]) => l.map(fn) // vemos que retorna una arrow function | |
| // ahora sí, podemos definir los efectos | |
| // Efecto duplica definido componiendo funciones | |
| def duplica = toList | |
| .andThen(map(PorDos)) | |
| .andThen(fromList) | |
| def alMenos7 = toList.andThen(map(_.max(7))).andThen(fromList) | |
| // Efecto definido como un objeto que extiende a la clase Funcion (Int) => Int | |
| object PorDos extends Function1[Int, Int] { | |
| override def apply(e: Int): Int = e * 2 | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment