Clase 9

Anuncio
Introducción al Alto Orden
Taller de Álgebra I
Primer cuatrimestre de 2015
Funciones como valores
Valores
Hasta ahora trabajamos con valores de distintos tipos:
I True, False (booleanos)
I 0, 1, -10, 100 (enteros)
I [1,2,3], [[]] (listas)
I (True, True) (tuplas)
I fact, reverso, fib (funciones)
¿Todos pueden ser parámetros de funciones? ¿Todos pueden
ser resultados? ¿Por qué no?
fact :: Integer -> Integer
fact ...
fib :: Integer -> Integer
fib ...
factOFib :: Bool -> ( Integer -> Integer )
factOFib True = fact
factOFib False = fib
Funciones como valores
cómo se usa
* Main > factOFib True 4
24
* Main > factOFib False 4
3
y un error
* Main > factOFib True
< interactive >:5:1:
No instance for ( Show ( Integer -> Integer ) )
( maybe you haven ’ t applied enough arguments to a
function ?)
arising from a use of ’ print ’
In a stmt of an interactive GHCi command : print it
* Main >
Funciones como valores
Implementar las siguientes funciones
I sumaproducida que toma un número y devuelve la función sumatoria
(sum) de listas en caso que el número sea mayor a 10, en caso contrario,
debe devolver la productoria de listas (product).
I Aplicar sumaproducida 8 a [1,2,3,4] (recordar que aplicar una función
es simplemente dejar un espacio luego del nombre.)
I Implementar una función f_rara que tome un booleano y devuelva
sumaproducida en caso de ser True (sino, estará indefinida). ¿Cuál es es
el tipo de esta función? (suponer sum :: [Integer] -> Integer)
f_rara :: Bool -> ?
Funciones como valores
¿Podrán estas funciones ser tomadas como parámetros?
Sea el tipo
data Jugada = Piedra | Papel | Tijera deriving ( Enum ,
Show )
Enum sirve para convertir los constructores en números:
*Main>
*Main>
0
*Main>
1
*Main>
2
data Jugada = Piedra | Papel | Tijera deriving (Enum, Show)
fromEnum Piedra
fromEnum Papel
fromEnum Tijera
Implementar la función ganaA :: Jugada -> Jugada -> Bool (que se
encargará de decidir si la primera le gana a la segunda).
ganaA Piedra Papel = False
...
Funciones como valores
Definamos la función juego:
juego e1 e2 regla | regla e1 e2 = e1
| regla e2 e1 = e2
| otherwise = error " empate :( "
¿Qué ocurre al evaluar lo siguiente?
Prelude> juego Piedra Tijera ganaA
¿Qué tipo tiene la función juego?
Funciones como valores
¿Podrán estas funciones ser tomadas como parámetros?
data Jugada = Piedra | Papel | Tijera deriving ( Enum ,
Show )
juego e1 e2 regla | regla e1 e2 = e1
| regla e2 e1 = e2
| otherwise = error " empate :( "
Sheldon Juega!
I Agregar Lagarto y Spock como constructores de Jugada.
I Crear una función ganaA’ de manera que se comporte como ganaA pero
agregando Lagarto y Spock.
I Ejecutar juego Spock Tijera ganaA’ y ver que devuelve Spock
Una conocida
Una sencilla
aplicar2Veces :: ( a -> a ) -> a -> a
aplicar2Veces f x = f ( f x )
¿Qué hace lo siguiente?
Prelude > aplicar2Veces not True
Prelude > aplicar2Veces ( not True )
¿Qué hace la siguiente función?
magia :: ( a -> b ) -> [ a ] -> [ b ]
magia _ [] = []
magia f ( x : xs ) = f x : magia f xs
Para entender el funcionamiento, probar lo siguiente
I magia not [True, True, False, True]
I magia reverse [[1,2,3], [5,6,7]]
I magia id [1,2,3,4,5,6]
Ası́ es! les presentamos a la función map. Muy útil y conocida, disponible en la
mayorı́a de los lenguajes.
Notación Lambda (ay chalay)
Nombres, ¿para qué?
I ¿Es necesario poner nombre a todas las funciones? ¿No serı́a cómodo
usarlas sin nombrarlas?
I La notación Lambda permite lidiar con este problema
¿Qué hacen las siguientes ejecuciones?
Prelude > (\ x -> x + 10) 20
Prelude > (\ radio -> (4 * pi * radio ** 3) /3 ) 6378
Prelude > map (\ x -> x + 10) [1 ,2 ,3 ,4]
Prelude > (\ x y -> x + y ) 20 30
Aplicación Parcial - El secreto de las flechas
¿Alguna vez se preguntaron por qué en Haskell se escribe:
f1 :: Int -> Int -> Int
en vez de
f2 :: ( Int , Int ) -> Int
como en la mayorı́a de los lenguajes? (ya lo notarán en los demás lenguajes)
¿Por qué pasa lo siguiente?:
ghci > max 4 5
5
ghci > ( max 4) 5
5
La magia está en los paréntesis
I En haskell t1 -> t2 -> t3 -> t4 -> t5
es equivalente a t1 -> (t2 -> (t3 -> (t4 -> t5)))
I De la misma manera f a b c d
es equivalente a (((f a) b) c) d
Ejercicios
I Dada la función suma: suma x y = x + y, ¿qué pasa al evaluar suma 1?
I Definir la función suc = suma 1 ¿qué ocurre al evaluar suc 10?
I suma x y define 2 funciones al mismo tiempo!
suma x devuelve una función que podemos reutilizar!
I ¿Qué tipo tiene suc? ¿Por qué?
I (*) Buscar el tipo de filter. Usando divisores, encontrar todos los
números con 6 divisores entre 1 y 1000.
I Encontrar todas las ternas de naturales a ≤ b ≤ c tales que
a + b + c = 1000 y a2 + b 2 = c 2 . (Obs:
https://projecteuler.net/problem=9)
I Los naturales a y b se dicen amigos si a 6= b y la suma de los divisores de
a menores que a es b y la suma de los divisores de b menores que b es a.
Por ejemplo, 220 y 284 son amigos, porque los divisores de 220 menores
que 220 son 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 que suman 284 y los
divisores de 284 menores que 284 son 1, 2, 4, 71, 142 que suman 220.
Encontrar la suma de todos los números amigos (es decir, que tienen un
amigo) menor a 10000. (Obs:
https://projecteuler.net/problem=21).
Descargar