Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
functional:scala [2013/04/03 20:49] alfred [Conceptos básicos] |
functional:scala [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 28: | Línea 28: | ||
| } | } | ||
| </code> | </code> | ||
| + | * ''ctrl+shift+f'' formatea el código. | ||
| ===== Conceptos ===== | ===== Conceptos ===== | ||
| ==== Conceptos básicos ==== | ==== Conceptos básicos ==== | ||
| Línea 55: | Línea 56: | ||
| } | } | ||
| </code> | </code> | ||
| + | |||
| === Sintaxis de código === | === Sintaxis de código === | ||
| Línea 118: | Línea 120: | ||
| === Listas === | === Listas === | ||
| - | === Excepciones === | + | Un objeto List contiene los siguientes métodos: |
| + | * ''.isEmpty'': Indica si la lista está vacía. | ||
| + | * ''.head'': Devuelve el primer elemento. | ||
| + | * ''.tail'': Devuelve el resto de elementos distintos al primero. | ||
| - | ==== Montar tests ==== | + | <code scala> |
| + | def sum(xs: List[Int]): Int = { | ||
| + | if (xs.isEmpty) 0 | ||
| + | else xs.head + sum(xs.tail) | ||
| + | } | ||
| + | def max(xs: List[Int]): Int = { | ||
| + | if (xs.isEmpty) throw new java.util.NoSuchElementException | ||
| + | if (!xs.tail.isEmpty) { | ||
| + | val m = max(xs.tail) | ||
| + | if (xs.head > m) xs.head | ||
| + | else m | ||
| + | } else xs.head | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | === Excepciones === | ||
| + | <code scala> | ||
| + | if (xs.isEmpty) throw new java.util.NoSuchElementException | ||
| + | </code> | ||
| + | ==== Montar tests ==== | ||
| + | * {{:functional:scala:test_jars.tar.gz|Jars para tests}} | ||
| ==== Funciones y evaluación ==== | ==== Funciones y evaluación ==== | ||
| + | Sintaxis de definición: | ||
| + | <code> | ||
| + | def nombre (par_name : tipo) : tipo_return = { ... } | ||
| + | </code> | ||
| + | Para indicar en Scala que un parámetro (en este caso el segundo) se evaluará por nombre, haremos: | ||
| + | <code> | ||
| + | def first (x: Double, y: => Double) = x | ||
| + | </code> | ||
| + | |||
| + | === Diferencia entre evaluación por nombre y por valor === | ||
| + | Teniendo... | ||
| + | <code scala> | ||
| + | square (x: Double) : Double = x * x | ||
| + | sumOfSquares (x: Double, y: Double) : Double = square(x) + square(y) | ||
| + | </code> | ||
| + | Por valor cada argumento se evalua una vez: | ||
| + | <code> | ||
| + | sumOfSquares(3, 2+2) | ||
| + | sumOfSquares(3, 4) | ||
| + | square(3) + square(4) | ||
| + | 3 * 3 + square(4) | ||
| + | 9 + square(4) | ||
| + | 9 + 4 * 4 | ||
| + | 9 + 16 | ||
| + | 25 | ||
| + | </code> | ||
| + | |||
| + | Por nombre cada argumento se evalua cuando es llamado: | ||
| + | <code> | ||
| + | sumOfSquares(3, 2+2) | ||
| + | square(3) + square(2+2) | ||
| + | 3 * 3 + square(2+2) | ||
| + | 9 + square(2+2) | ||
| + | 9 + (2+2) * (2+2) | ||
| + | 9 + 4 * (2+2) | ||
| + | 9 + 4 * 4 | ||
| + | 25 | ||
| + | </code> | ||
| + | |||
| + | Si tuviesemos la siguientes expresiones | ||
| + | <code> | ||
| + | def loop () = loop | ||
| + | def first (x: Double, y: Double) = x | ||
| + | first(x, loop) | ||
| + | </code> | ||
| + | Si evaluamos la tercera por nombre terminaría pero si la evaluamos por valor cae en bucle infinito. \\ | ||
| + | Cuando definimos usando ''val'' lo hacemos haciéndolo por valor. Cuando lo hacemos usando ''def'' lo hacemos por nombre: | ||
| + | <code> | ||
| + | def loop () : Boolean = loop | ||
| + | def x = loop | ||
| + | val x = loop // bucle infinito | ||
| + | </code> | ||
| + | |||
| + | ==== Notas ==== | ||
| + | * Cuando tenemos una función recursiva necesitamos indicar su valor devuelto. | ||