Sei sulla pagina 1di 30

LPP 2012-2013

Tema 6: Programacin funcional en Scala


1
LPP 2012-2013
Objetivos
Ser capaz de comprender y escribir programas sencillos en Scala que utilicen las
caractersticas de Programacin Funcional utilizadas en Scheme: programacin declarativa,
valores inmutables, listas, funciones como objetos de primera clase, mbitos y clausuras
Ser capaz de comprender y escribir programas sencilos en Scala que amplan las
caractersticas de Programacin Funcional utilizadas en Scheme: variables y funciones
tipeadas, denicin por comprensin de colecciones y currying
2
LPP 2012-2013
Referencias
Martin Odersky: Programming in Scala
Cay S. Horstmann: Scala for the impatient, Addison-Wesley Professional,
2012.
Martin Odersky, A Postfunctional Language
Mario Gleichman, Serie de posts Functional Scala
3
LPP 2012-2013
Programacin
declarativa
No hay pasos de
ejecucin
Valores inmutables
No hay efectos laterales
Recursin
Listas
Funciones como
objetos de primera
clase
Funciones de orden
superior
Closures
Caractersticas funcionales de Scala
Caractersticas funcionales de Scheme y Scala
Funciones y variables tipeadas
Denicin por comprensin y pattern
matching de listas y secuencias
Currying
Caractersticas funcionales de Scala
Functional programming is a
programming paradigm that treats
computation as the evaluation of
mathematical functions and avoids
state and mutable data
Denicin de programacin funcional
en Scala in Action:
4
LPP 2012-2013
Caractersticas funcionales de Scala
Variables y funciones tipeadas: funciones
Como hemos visto en el seminario, Scala es un lenguaje strictamente tipeado:
todas las variables, funciones y parmetros tienen un tipo denido, y el compilador
detecta un error cuando usamos un valor de un tipo que no corresponde al tipo de
la variable o del parmetro. Scala puede inferir el tipo devuelto por la funcin.
Tuplas: las tuplas se denen entre parntesis con los tipos de sus elementos
entre comas
def max(x: Int, y: Int): Int = if (x > y) x else y
(Int,Int) => Int
Prototipo (rma) de la funcin: se declaran entre parntesis los tipos de los argumentos y
despus de la echa el tipo del resultado de la funcin. Scala tambin utiliza esta notacin para
denir funciones annimas (lo veremos ms adelante)
5
val t: (Int, String, Double) = (21, "Veintiuno", 21.0)
LPP 2012-2013
Caractersticas funcionales de Scala
Variables y funciones tipeadas: colecciones (Listas)
Colecciones: las colecciones se denen en Scala como clases genricas en
las que es necesario denir el tipo de los elementos contenidos. Para ello se
debe denir entre corchetes el tipo de los valores contenidos en el dato
compuesto.
val miListaInt: List[Int] = List(1,2,3)
val miListaString: List[String] = List("Hola","que","tal")
6
La clase List es una estructura inmutable a la que podemos aplicar mtodos como:
!"# lista vaca
$%&' devuelve el primer elemento de la lista
(&"# devuelve el resto
")*+,(- comprueba si la lista es vaca
.. devuelve una nueva lista aadiendo un elemento a su cabeza (/01) de Scheme)
... devuelve una nueva lista concatenando dos listas (&,,%1' de Scheme)
val lista: List[Int] = List(1, 2, 3, 4)
val primero = lista.head
val resto = lista.tail
val dobleLista = primero :: resto ::: lista
LPP 2012-2013
Caractersticas funcionales de Scala
Variables y funciones tipeadas: Qu es Any?
El tipo 21- es el tipo (o clase) padre de todos los tipos de Scala, es similar a
la clase 345%/( de Java. Cualquier objeto es de tipo 21-.
Mtodos ")61)(&1/%37 y &)61)(&1/%37 comprueban si el valor almacenado
en una variable de tipo 21- es de otro tipo y permiten recuperarlo como un
objeto de ese tipo
val s: String = "Hola"
val cualquierTipo: Any = s
al ser de tipo Any puede contener cualquier tipo de valor
val listaCualquiera: List[Any] = List("Hola",1,"Adios",2)
scala> val cualquierTipo: Any = "Hola"
scala> cualquierTipo.isInstanceOf[String]
res1: Boolean = true
scala> cualquierTipo.asInstanceOf[String]
res2: String = Hola
7
LPP 2012-2013
Caractersticas funcionales de Scala
Denicin de funciones de forma declarativa
En Scala utilizando el paradigma funcional no debemos utilizar bucles ni
pasos de ejecucin. Al igual que hacamos en Scheme, la funcin debe
quedar denida en una nica sentencia. Pero en esa sentencia pueden haber
llamadas anidadas a otras funciones o sentencias adicionales:
Permitimos denir variables locales inmutables al comienzo de las
deniciones de las funciones:
def max3(x: Int, y: Int, z: Int): Int = max(max(x,y),z)
def max3(x: Int, y: Int, z: Int): Int = {
val maxPrimeros = max(x,y)
max(maxPrimeros,z)
}
8
LPP 2012-2013
Caractersticas funcionales de Scala
Valores inmutables
Variables mutables e inmutables: en Scala se recomienda utilizar variables
de tipo 8&# para reforzar el carcter funcional y evitar los efectos laterales en
los programas. Una variable de tipo 8&# no puede ser modicada (re-
asignada a otro objeto).
Tipos mutables e inmutables: Independientemente del tipo de mutabilidad
de las variables, en Scala tambin se diferencia entre tipos mutables y tipos
inmutables. Las estructuras de datos inmutables no pueden ser modicadas
una vez creadas. Los tipos mutables si pueden modicarse. Por ejemplo, la
clase List es inmutable, mientras que la clase Array es mutable.
val num = 1
num = num + 1 Error al intentar reasignar una
variable inmutable
inmutable
var num = 1
num = num + 1
mutable
no hay error
val numbers = Array(1, 2, 3, 4)
val num = numbers(3)
numbers(3) = 100
val numCambiado = numbers(3)
Almacena un objeto de tipo mutable
variable inmutable
9
LPP 2012-2013
Caractersticas funcionales de Scala
Uso de la recursin
Nmero de elementos de una lista:
Insercin en una lista ordenada:
Ordenacin de una lista:
Reverse-list:
def numElems(lista:List[Int]):Int =
if (lista.isEmpty) 0 else
1 + numElems(l.tail)
def insert(x: Int, lista: List[Int]) : List[Int] =
if (lista == Nil) x :: Nil else
if (x < lista.head) x :: lista else
lista.head :: insert(x, lista.tail)
def sort(lista: List[Int]): List[Int] =
if (lista.isEmpty) Nil else
insert(lista.head, sort(lista.tail))
def reverse(lista: List[Int]) : List[Int] =
if (lista.isEmpty) Nil else
reverse(lista.tail) ::: List(lista.head)
10
LPP 2012-2013
Caractersticas funcionales de Scala
Funciones como objetos de primera clase
En Scala las funciones tambin son objetos de primera clase
Las funciones de orden superior son funciones que utilizan otras
funciones como parmetros, tambin las tenemos en Scala.
Se puede pasar
como argumento a
otra funcin
Se puede devolver como
resultado de otra
funcin, construyndolas
en tiempo de ejecucin
(closures)
Se puede ligar a
variables
Almacenar
funciones en
estructuras de
datos como listas
11
LPP 2012-2013
Funciones como objetos de primera clase
Creando funciones annimas
(x: Int, y: Int) => {x + y}
(lambda (x y)
(+ x y))
Funcin annima en Scala
Funcin annima en Scheme
Espera dos
argumentos de
tipo Int
Cuerpo de la
funcin
Dene un objeto funcin sin nombre
Prototipo de la funcin:
(Int, Int) => Int
Se inere el
tipo de retorno
Podemos guardarla en una variable:
val fun = (x: Int, y: Int) => x + y
Podemos poner el tipo de la variable:
val fun: (Int, Int) => Int =
(x: Int, y: Int) => x + y
Se pueden quitar las llaves
al tener slo una sentencia
en el cuerpo de la funcin
Llamada a la funcin:
fun(2,3) 5
12
LPP 2012-2013
Funciones como objetos de primera clase
Sintaxis de los huecos o placeholders
En Scala, para usar funciones como objetos de primera clase, debemos
utilizar la sintaxis de huecos (placeholders) para indicar que no se tiene que
evaluar la funcin.
Tambin es posible utilizar la sintaxis de placeholders para dejar libres ciertos
argumentos de la funcin y jar algunos otros. De esta forma podemos
transformar una funcin en otra de menos argumentos.
def suma3(a: Int, b: Int, c: Int) = a + b + c
val f = suma3 _
f(1,2,3) -> 6
Esta sintaxis es necesaria para trabajar
con funciones de primera clase, ya que
debemos indicarle al compilador que no se
tienen que evaluar hasta que no se utilicen
val f : (Int) => Int = suma3(10, _: Int, 5)
f(3) 18
Esta expresin guarda en la variable f una funcin de un nico parmetro construida a partir de
la funcin )9+&: y jando el primer y ltimo argumento a los valores 10 y 5. La funcin guardada
en la variable 7 slo tiene un argumento y devuelve el resultado de llamar a )9+&: pasando ese
argumento y los valores a = 10 y c = 5
13
LPP 2012-2013
Funciones como objetos de primera clase
Funciones como argumento
sumatorio(f,a,b) = f(a)+sumatorio(f,a+1,b)
sumatorio(f,a,b) = 0 si a > b
Sumatorio:
def sumatorio(a: Int, b:Int, f:(Int) => Int): Int = {
if (a > b) 0 else
f(a) + sumatorio(a+1,b,f)
}
Sumatorio en Scala:
Recibe como arg una funcin f que
recibe un Int y devuelve un Int
Llamada a Sumatorio con una funcin annima:
sumatorio(1, 10, (x:Int) => {x+3})
Funcin annima que suma 3 a su
argumento
sumatorio(1, 10, (x) => {x+3})
Podemos dejar que el compilador inera el
tipo, sabe que es un Int por el tipo del tercer
argumento de sumatorio: (Int) => Int
sumatorio(1, 10, x => x+3 )
sumatorio(1, 10, _+3 )
Notacin ms concisa: eliminamos
parntesis y llaves
Equivalente con la sintaxis de los huecos: slo se puede usar
cuando se recibe un argumento y la funcin opera sobre l
Llamada a Sumatorio con una funcin ya creada:
def suma3(x:Int) = x+3
sumatorio(1,10,suma3 _)
14
LPP 2012-2013
Funciones como objetos de primera clase
Funciones como elementos de listas
Al igual que en Scheme es posible guardar funciones en otras estructuras.
Por ejemplo, podemos crear una lista de funciones, pero todas las funciones
deben tener la misma signatura (prototipo o rma), que ser el tipo de los
elementos de la lista:
Ejemplo de funcin que toma una lista de funciones de un argumento y las
aplica a un nmero de forma correlativa:
def suma3(a: Int, b: Int, c: Int) = a + b + c
def mult3(a: Int, b: Int, c: Int) = a * b * c
val listaFuncs: List[(Int,Int,Int)=>Int] = List(suma3 _, mult3 _, (x:Int,y:Int,z:Int)=>x+y*z)
val f = listaFuncs.head
f(1,2,3)
Los elementos de la lista son funciones que reciben como
argumentos 3 Int y devuelven un Int
placeholders para que no se evalen las funciones
def aplicaLista (lista: List[(Int) => Int], x: Int): Int =
if (lista.length == 1) lista.head(x) else
lista.head(aplicaLista(lista.tail,x))
def mas5(x: Int) = x+5
def por8(x: Int) = x*8
val l = List(mas5 _, por8 _, suma3(1, _: Int, 10))
aplicaLista(l, 10)
se crea una funcin de un argumento a partir de la funcin de 3 argumentos )9+&:
utilizando la sintaxis de huecos: se da valor jo al primer y ltimo argumento, y el
segundo se deja pendiente con un placeholder
15
LPP 2012-2013
Funciones como objetos de primera clase
Funciones como valores devueltos
Las funciones pueden crearse en la invocacin de otras funciones y ser
devueltas como resultado.
Por ejemplo, la siguiente funcin construye y devuelve un sumador que suma
el nmero que pasamos como parmetro. La funcin devuelta es una
clausura.
def makeSumador(k: Int) = {
(x: Int) => x + k
}
val f: (Int) => Int = makeSumador(10)
val g: (Int) => Int = makeSumador(100)
f(4)
g(4)
La funcin +&;%<9+&'0= devuelve una funcin, por lo que
podramos haber declarado su tipo retorno como
>61(? AB 61(C hemos dejado que el compilador lo inera
def makeSumador(k: Int): (Int) => Int = {
(x: Int) => x + k
}
El tipo de las variables (funcin que recibe un Int y
devuelve un Int) tambin podra haberlo inferido el
compilador, pero lo indicamos por claridad
16
LPP 2012-2013
mbitos: funcionamiento igual que en Scheme
Una invocacin a una funcin crea un nuevo mbito en el que se evala el
cuerpo de la funcin. Lo llamamos mbito de evaluacin de la funcin
El mbito de evaluacin se crea dentro del mbito en el que se cre la
funcin (deep binding)
Los argumentos de la funcin son variables locales de este nuevo mbito que
quedan ligadas a los parmetros que se utilizan en la llamada
En el nuevo mbito se pueden denir otras variables locales
En el nuevo mbito se pueden acceder al valor de las variables del mbito
padre
17
LPP 2012-2013
mbitos en Scala
1. En el mbito principal del intrprete se dene el
valor de las variables x (10) e y (20), as como la
funcin prueba.
2. La ejecucin de prueba(3) crea un nuevo mbito
de evaluacin, dentro del mbito principal, en el
que se ejecuta el cuerpo de la funcin.
3. En el mbito de evaluacin se liga el valor de z
(argumento de prueba) con el valor 3 (parmetro
con el que se realiza la llamada).
4. En este nuevo mbito se ejecuta el cuerpo de la
funcin: se crea la variable local x con el valor 0
y se evala la expresin x+y+z. El valor de x y z
estn denidos en el propio mbito local (0 y 3).
El valor de y se obtiene del entorno padre: 20. El
resultado es 23.
val x = 10
val y = 20
def prueba(z: Int): Int = {
val x = 0
x+y+z
}
prueba(3)
23
x: 10
y: 20
z: 3
x: 0
x + y + z --> 23
mbito evaluacin ,=9%4&
18
LPP 2012-2013
mbitos en Scala
En primer lugar se realizan las
invocaciones a g. Cada una crea un
mbito local en el que se evala la
funcin. Las invocaciones devuelven
13 y 15 respectivamente.
Despus se realiza la invocacin a f
con esos valores 13 y 15. Esta
invocacin vuelve a crear un mbito
local en el que se evala la expresin +
+y+z, devolviendo 33.
19
def f(x: Int, y: Int):
Int = {
val z = 5
x+y+z
}
def g(z: Int): Int = {
val x = 10
z+x
}
f(g(3),g(5))
LPP 2012-2013
mbitos en Scala
Ejemplo con variables locales y globales
En el mbito principal del intrprete se dene el
valor de las variables x (10) e y (20), as como la
funcin prueba.
La ejecucin de prueba(3) crea un nuevo mbito
de evaluacin, dentro del mbito principal, en el
que se ejecuta el cuerpo de la funcin.
En el mbito de evaluacin se liga el valor de z
(argumento de prueba) con el valor 3 (parmetro
con el que se realiza la llamada).
En este nuevo mbito se ejecuta el cuerpo de la
funcin: se crea la variable local x con el valor 0 y
se evala la expresin x+y+z. El valor de x y z
estn denidos en el propio mbito local (0 y 3). El
valor de y se obtiene del entorno padre: 20. El
resultado es 23.
20
val x = 10
val y = 20
def g(y: Int): Int = {
x+y
}
def prueba(z: Int):
Int = {
val x = 0
g(x+y+z)
}
prueba(3)
LPP 2012-2013
Clausuras en Scala
Ejemplos
Cambiamos la denicin de ,=9%4&
haciendo que tome como parmetro
la variable - y que devuelva una
funci n anni ma construi da en
tiempo de ejecucin: la funcin
>D.61(? AB EFG-GDH que tiene
como parmetro D y como variables
libres F e -.
La funcin devuelta es una clausura
que se crear en al mbito de
evaluacin de ,=9%4& y quedar
asociada a ese mbito en el momento
en que se ejecute ,=9%4&.
val x = 10
val y = 20
def prueba(y: Int): (Int)=>Int = {
val x = 0
(z:Int) => {x+y+z}
}
val f = prueba(2)
f(3)
x: 10
y: 20
y: 2
x: 0
mbito evaluacin ,=9%4&
arg: z
body: x+y+z
f:
mbito evaluacin 7
z: 3
x+y+z --> 5
5
21
LPP 2012-2013
Clausuras en Scala
Ejemplos
def makeSumador(k: Int): (Int)=>Int = (x: Int) => x + k
val f = makeSumador(10)
val g = makeSumador(100)
f(4)
g(4)
k: 10
mbito evaluacin +&;%<9+&'0=
arg: x
body: x+k
f:
mbito evaluacin 7
x: 4
x+k --> 14
k: 100
mbito evaluacin +&;%<9+&'0=
arg: x
body: x+k
g:
mbito evaluacin I
x: 4
x+k --> 104
22
LPP 2012-2013
Clausuras en Scala
Ejemplos
La llamada a 791/J hace que se evalue su cuerpo. En l se crea la variable F con el valor 10 y la expresin f=func1
() asocia f con la clausura devuelta por func1. Esta clausura es ()=>{x+1} creada en el mbito de evaluacin de
func1. En ese mismo mbito se ha creado tambin la variable x con el valor 1. La llamada a f en el cdigo
equivalente hace que la funcin se evalue. Es en este momento cuando el resultado cambia en funcin de si el
lenguaje funciona con deep binding o shallow binding:
Si el lenguaje funciona con deep binding el mbito de evaluacin de f se crea en el mbito de evaluacin de func1,
en el que x vale 1. El resultado de la llamada sera 2.
Si el lenguaje funciona con shallow binding el mbito de evaluacin de f se crea en el propio mbito en el que se
realiza la llamada, en el que x vale 10. El resultado de la llamada sera 11.
Si ejectuamos el cdigo veremos que devuelve 2. Por lo que estamos en el segundo caso. Scala usa deep binding.
val x = 100
def func1(): () => Int = {
val x=1
() => {x+1}
}
def func2(): Int= {
val x=10
val f=func1()
f()
}
func2()
(define x 100)
(define (func1)
(let ((x 1))
(lambda ()
(+ x 1))))
(define (func2)
(let ((x 10))
((func1))))
(func2)
En Scala y Scheme, que usan deep binding, se devolver 2.
Los lenguajes que usen shallow binding se devolver 11.
23
LPP 2012-2013
Funciones de orden superior
La denicin de funciones como un tipo de dato primitivo permite denir funciones de orden superior
que toman como parmetro otras funciones y permiten hacer mucho ms conciso y general el
cdigo escrito en Scala. Ejemplos de mtodos de orden superior de la clase K")(:
/091( LLB cuenta el nmero de elementos de la lista que satisfacen un predicado
%F")() LLB comprueba si algn elemento de la lista satisface un predicado
7"#(%= --> devuelve una nueva lista con los elementos de la lista original que cumplen el
predicado
+&, --> aplica una funcin a todos los elementos de la lista, devolviendo una nueva lista con el
resultado
Al ser mtodos y no funciones s que se pueden denir como genricos y aplicar a listas de distintos
tipos. El tipo de la funcin que se pasa como argumento tiene que corresponder con el tipo de los
elementos de la lista
24
LPP 2012-2013
Funciones de orden superior
/091(C 7"#(%=C +&,
El tipo de la funcin que se pasa como argumento a las funciones de orden
superior es genrico y tiene que corresponder al tipo de los elementos de la
lista.
Distintas formas (equivalentes) de escribir la funcin que pasamos como
argumento:
val lista = List(1,2,3,4,5,6,7,8,9)
lista.count((x:Int) => {x % 2 == 0})
lista.count((x) => {x % 2 == 0})
lista.count(x => x % 2 == 0)
lista.count(_ % 2 == 0)
def par(x:Int): Boolean = {x % 2 == 0}
lista.count(par _)
4
lista.filter(par _)
def cuadrado(x:Int) = x*x
lista.map(cuadrado _)
List("No","es","elegante","escribir","con","mayusculas").map(s => s.toUpperCase)
List(2, 4, 6, 8)
List(1, 4, 9, 16, 25, 36, 49, 64, 81)
List(NO, ES, ELEGANTE, ESCRIBIR, CON, MAYUSCULAS)
25
LPP 2012-2013
Funciones de orden superior
Implementacin recursiva
Funcin +"M091(, que cuenta el nmero de elementos de una lista de tipo
61( que cumplen un predicado:
Funcin +"N&,, que aplica una funcin a todos los elementos de una lista:
def miCount(lista:List[Int], p:(Int)=>Boolean): Int = {
if (lista == Nil) 0 else
if (p(lista.head)) 1 + miCount(lista.tail,p) else
miCount(lista.tail,p)
}
def miMap(lista:List[Int], f:(Int)=>Int): List[Int] = {
if (lista == Nil) Nil else
f(lista.head) :: miMap(lista.tail,f)
}
26
LPP 2012-2013
Funciones genricas
En Scala tambin es posible denir funciones con tipos de datos genricos. Por ejemplo, la
funcin 7"#(%= utiliza el tipo genrico A como el tipo de los elementos de la lista y el tipo del
predicado que se aplica a los elementos. El compilador determina el tipo A cuando se invoca
a la funcin con una lista y un predicado concreto.
27
def filter[A](lista: List[A], pred: (A)=>Boolean): List[A] = {
if (lista.isEmpty) Nil else
if (pred (lista.head)) lista.head :: filter(lista.tail, pred)
else filter(lista.tail, pred)
}
def par(x: Int) = x % 2 == 0
filter(List(1,2,3,4), par _)
// List[Int] = List(2, 4, 6)
filter(List("hola","amigo","adios"),(s: String)=>{s.head=='a'})
// List[java.lang.String] = List(amigo, adios)
LPP 2012-2013
Funciones genricas
19+*#%+):
=%8%=)%:
"1)%=(:
)0=(:
28
def numElems[A](lista:List[A]):Int =
if (lista.isEmpty) 0 else
1 + numElems(lista.tail)
def reverse[A](lista: List[A]) : List[A] =
if (lista.isEmpty) Nil else
reverse(lista.tail) ::: List(lista.head)
def insert[A](x: A, lista: List[A], menor: (A,A) => Boolean) : List[A] =
if (lista == Nil) x :: Nil else
if (menor(x,lista.head)) x :: lista else
lista.head :: insert(x, lista.tail, menor)
def sort[A](lista: List[A], menor: (A,A) => Boolean): List[A] =
if (lista.isEmpty) Nil else
insert(lista.head, sort(lista.tail, menor), menor)
LPP 2012-2013
Denicin por comprensin de colecciones
70=OOO-"%#'
Mat emt i cament e, una deni ci n por
comprensin de un conjunto se realiza con una
denicin lgica de una propiedad que deben
satisfacer sus elementos.
Muchos lenguajes de programacin funcional,
como Scala, permiten denir colecciones
utilizando estas propiedades. Las colecciones
tienen que tener un nmero nito de elementos.
Denicin:
{ x! | x ! N : x ! {1..5} }
conjunto los cinco primeros nmeros naturales
elevados al cuadrado
propiedad
for (x <- (1 to 5)) yield x*x
devuelve un rango de nmeros del 1
al 5 (una coleccin)
aplica la funcin denida tras el -"%#' a todos los elementos
del rango y devuelve una coleccin del mismo tipo que el
dominio de entrada transformada con la expresin
for (x <- List.range(1,6)) yield x*x
devuelve una lista con los 5 primeros
nmeros elevados al cuadrado
el 6 no est incluido
for (i <- List.range(1, 101) if i % 2 != 0) yield i*i
devuelve el cuadrado de los nmeros
impares del 1 al 100
condicin que deben cumplir los nmeros: tienen que ser impares
for (i <- List.range(1, 101) if (i % 2 != 0 && i % 3 == 0)) yield i*i devuelve el cuadrado de los
nmeros impares divisibles por 3
for(x <- (1 to 3 ); y <- (1 to x)) yield (x,y)
dos generadores: El primero (1 to 3) dene los primeros nmeros de las parejas y el segundo (1 to x)
utiliza la variable del primer generador como tope para obtener los valores de los segundos nmeros
(1,1), (2,1), (2,2), (3,1), (3,2), (3,3)
29
LPP 2012-2013
Currying
Currying es el proceso de convertir una funcin que toma dos argumentos en
una funcin que toma un argumento y devuelve una funcin que recibe el
segundo argumento.
En Scala existe una forma abreviada de denir currying:
def mulUnoCadaVez(x: Int) = (y: Int) => x * y
funcin toma un argumento, devolviendo una
funcin que toma un argumento
mulUnoCadaVez(6)(7)
llamada para multiplicar dos nmeros
el resultado de mulUnoCadaVez(6) es la clausura (y: Int)=>x*y con el valor x
asociado a 6. Esta funcin se aplica a 7, devolviendo 42.
def mulUnoCadaVez(x: Int)(y: Int) = x * y;
la funcin mulUnoCadaVez toma un argumento y
devuelve una funcin que toma un argumento
30

Potrebbero piacerti anche