Skip to content

Instantly share code, notes, and snippets.

@juanbono
Last active December 9, 2016 19:10
Show Gist options
  • Save juanbono/6603cb87f3695cab0c0581d3835f25be to your computer and use it in GitHub Desktop.
Save juanbono/6603cb87f3695cab0c0581d3835f25be to your computer and use it in GitHub Desktop.
Recuperatorio del Paradigma Funcional, año 2016
-- Enlace: https://docs.google.com/document/d/1TTaIK1kPWuhkvWnnlf9SZSodBtSXhiewOAex4wNtSps
{-
data Raton = UnRaton String Float Float [Enfermedad] deriving
(Show, Eq)
-}
-- Se puede declarar el tipo de dato de esta forma, asi nos ahorramos
-- declarar manualmente las funciones para obtener cada componente de
-- un raton.
data Raton = UnRaton {
nombre :: String,
edad :: Float,
peso :: Float,
enfermedades :: [Enfermedad]
} deriving (Show, Eq)
type Enfermedad = String
cerebro :: Raton
cerebro = UnRaton "Cerebro" 9.0 0.2 ["brucelosis", "sarampion", "tuberculosis"]
{-
1- Hacer 4 funciones de modificacion de raton:
* modificarNombre
* modificarEdad
* modificarPeso
* modificarEnfermedades
Deben recibir el raton y una funcion y devolver el raton modificado.
-}
modificarNombre :: (String -> String) -> Raton -> Raton
modificarNombre f (UnRaton n e p enfs) = UnRaton (f n) e p enfs
modificarEdad :: (Float -> Float) -> Raton -> Raton
modificarEdad f (UnRaton n e p enfs) = UnRaton n (f e) p enfs
modificarPeso :: (Float -> Float) -> Raton -> Raton
modificarPeso f (UnRaton n e p enfs) = UnRaton n e (f p) enfs
modificarEnfermedades :: ([Enfermedad] -> [Enfermedad]) -> Raton -> Raton
modificarEnfermedades f (UnRaton n e p enfs) = UnRaton n e p (f enfs)
-- 2- Existen distintos tipos de hierbas que afectan (modifican) de diferentes
-- maneras al raton. Definir dichas hierbas
-- a. hierbaBuena, que rejuvenece al raton a la raiz cuadrada de su edad.
hierbaBuena :: Raton -> Raton
hierbaBuena raton = modificarEdad sqrt raton
-- o tambien su definicion mas concisa:
hierbaBuena2 :: Raton -> Raton
hierbaBuena2 = modificarEdad sqrt
-- b. hierbaVerde, elimina las enfermedades que terminen de cierta forma
hierbaVerde :: String -> Raton -> Raton
hierbaVerde terminacion raton = modificarEnfermedades (filter (noTerminaCon terminacion)) raton
-- o su forma mas concisa:
hierbaVerde2 :: String -> Raton -> Raton
hierbaVerde2 terminacion = modificarEnfermedades (filter (noTerminaCon terminacion))
-- funciones auxiliares
-- Toma los n caracteres de un String.
losUltimos :: Int -> String -> String
losUltimos n = reverse . take n . reverse
-- Verifica si una palabra termina con cierta terminacion.
noTerminaCon :: String -> String -> Bool
noTerminaCon terminacion palabra = losUltimos (length terminacion) palabra /= terminacion
-- c. alcachofa, hace que el raton pierda peso en un 10% si pesa mas de 2kg,
-- sino pierde un 5%
alcachofa :: Raton -> Raton
alcachofa raton = modificarPeso perderPeso raton
-- o
alcachofa2 :: Raton -> Raton
alcachofa2 = modificarPeso perderPeso
-- funcion que se encarga de decidir si pierde 10% o 5% del peso.
perderPeso :: Float -> Float
perderPeso p
| p > 2 = p * 0.9 -- pierde 10% del peso.
| otherwise = p * 0.95 -- pierde 5% del peso.
-- 3- Medicamentos, las hierbas se utilizan para crear medicamentos, definidos como:
type Medicamento = Raton -> Raton
-- a. Hacer la funcion medicamento, que dada una lista de hierbas crea un medicamento
-- el cual aplica todas ellas.
medicamento :: [Medicamento] -> Raton -> Raton
medicamento listaDeHierbas raton = foldl tomarHierba raton listaDeHierbas
-- tomarHierba recibe un raton y una hierba y hace que el raton tome la hierba.
-- Si pensamos a las hierbas como una funcion cualquiera y al raton como su parametro.
-- tomarHierba lo que hace es recibir un parametro y una funcion y aplicar la funcion al parametro.
-- Pero es importante observar el orden con que los recibe.
tomarHierba :: a -> (a -> b) -> b
tomarHierba r h = h r
-- una version recursiva de medicamento:
medicamento2 :: [Medicamento] -> Raton -> Raton
medicamento2 [] raton = raton
medicamento2 (hierba:hierbas) raton = medicamento2 hierbas (hierba raton)
-- una version usando foldl y una expresion lambda en vez de una funcion auxiliar:
medicamento3 :: [Medicamento] -> Raton -> Raton
medicamento3 listaDeHierbas raton = foldl (\r h -> h r) raton listaDeHierbas
-- b. pondsAntiAge que es un medicamento que esta hecho con 3 hierbas buenas y una alcachofa
pondsAntiAge :: Medicamento
pondsAntiAge = medicamento [hierbaBuena, hierbaBuena, hierbaBuena, alcachofa]
-- c. reduceFatFast, (que viene en distintas potencias) y es un medicamento compuesto por una
-- hierba verde de "obesidad" y tantas alcachofas como indique su potencia
reduceFatFast :: Int -> Medicamento
reduceFatFast potencia = medicamento (hierbaVerde "obesidad" : replicate potencia alcachofa)
-- 4. Experimentos: Los laboratorios antes de publicar un medicamento, lo prueban con distintos
-- ratones para evaluar resultados:
-- a. Hacer la funcion estanMasLindosQueNunca, que recibe muchos ratones y un medicamento,
-- y es cierto cuando cada uno pesa menos de 1 kg despues de aplicarle el medicamento dado.
estanMasLindosQueNunca :: [Raton] -> Medicamento -> Bool
estanMasLindosQueNunca ratones med = all (\raton -> (peso . med) raton < 1) ratones
-- alternativa muy similar, reemplazando la expresion lambda por composicion de funciones.
estanMasLindosQueNunca2 :: [Raton] -> Medicamento -> Bool
estanMasLindosQueNunca2 ratones med = all ((<1).peso.med) ratones
-- una alternativa usando una funcion auxiliar para delegar logica:
estanMasLindosQueNunca3 :: [Raton] -> Medicamento -> Bool
estanMasLindosQueNunca3 ratones med = all (pesaPocoTrasMedicamento med) ratones
-- funcion auxiliar que usa composicion de funciones para aplicar el medicamento,
-- obtener el peso del raton y luego comparar este peso para saber si es menor que 1.
pesaPocoTrasMedicamento :: Medicamento -> Raton -> Bool
pesaPocoTrasMedicamento med = (< 1) . peso . med
-- alternativa recursiva:
estanMasLindosQueNunca4 :: [Raton] -> Medicamento -> Bool
estanMasLindosQueNunca4 [] _ = True
estanMasLindosQueNunca4 (raton:ratones) med = peso (med raton) < 1 && estanMasLindosQueNunca3 ratones med
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment