En los lenguajes funcionales un programa es un conjunto de ecuaciones orientadas que definen una o más funciones.
doble x = 2 * x
suma x y = x + y
normaVec x1 x2 = sqrt (x1^2 + x2^2)
cte8 x = 8
-- pattern matching
-- Si evalúo f en 0 me va a devolver 1, porque va a escapar
-- el programa luego de la primera línea
-- Si n /= 0 va a evaluar la segunda línea.
f 0 = 1
f n = 0
signo n | n > 0 = 1
| n == 0 = 0
| otherwise = -1
maximo x y | x >= y = x
| otherwise = y
-- Non-exhaustive patterns, la función no está definida para los reales < 3
f1 n | n >= 3 = 5
-- Podemos explicitar con undefined
f3 n | n >= 3 = 5
| n == 2 = undefined
| otherwise = 8
-- Cuando dos guardas se solapan su orden define el comportamiento de la función
-- Si n > 4, para f4 el la imagen de n es 5, para f5 es 7
f4 n | n >= 3 = 5
| n <= 9 = 7
f5 n | n <= 9 = 7
| n >= 3 = 5
cantidadDeSoluciones b c | d > 0 = 2
| d == 0 = 1
| otherwise = 0
where d = b ^2 - 4* c
Conjunto de valores a los que se les puede aplicar un conjunto de funciones.
Podemos especificar explícitamente el tipo de datos del dominio y codominio de las funciones que definimos. A esto lo llamamos dar la signatura de la función.
Int
$= (\Z, \{+, \space-, \space *, \text{ div}, \text{ mod}\})$Float
$= (\mathbb Q, \{+, \space-, \space *, \space /\})$Bool
$= (\{\text{True, False}\}, \{\&\&, \space||, \text{ not}, \})$-- Especificar signatura de una función
esPar :: Int -> Bool
esPar n | mod n 2 == 0 = True
| otherwise = False
esImpar :: Int -> Bool
esImpar n = not (esPar n)
module Ejercicios01 where
{- |absoluto:
devuelve el valor absoluto de un número entero -}
absoluto :: Int -> Int
absoluto x | x >= 0 = x
| x < 0 = x * (-1)
| otherwise = undefined -- this line makes no absolute sense but it makes the extension shut the fuck up so it'll stay
{- |maximoabsoluto:
devuelve el máximo entre el valor absoluto de dos números enteros -}
maximoAbsoluto :: Int -> Int -> Int
maximoAbsoluto x y | a > b = a
| b > a = b
| otherwise = undefined
where a = absoluto x
b = absoluto y
{- |maximo3:
devuelve el máximo entre tres números enteros -}
maximo3 :: Int -> Int -> Int -> Int
maximo3 x y z | x > y && x > z = x
| y > x && y > z = y
| z > x && z > y = z
| otherwise = undefined
{- |algunoEs0:
dados dos números racionales, decide si alguno de los dos es igual a 0
(hacerlo dos veces, una sin usar y otra usando pattern matching) -}
algunoEs0 :: Float -> Float -> Bool
algunoEs0 0 _ = True
algunoEs0 _ 0 = True
algunoEs0 _ _ = False
algunoEs02 :: Float -> Float -> Bool
algunoEs02 x y | x == 0 = True
| y == 0 = True
| otherwise = False
{- |ambosSon0:
dados dos números racionales, decide si ambos son iguales a 0
(hacerlo dos veces, una sin usar y otra usando pattern matching) -}
ambosSon0 :: Float -> Float -> Bool
ambosSon0 0 0 = True
ambosSon0 _ _ = False
ambosSon02 :: Float -> Float -> Bool
ambosSon02 x y | x == 0 && y == 0 = True
| otherwise = False
{- |esMultiploDe:
dados dos números naturales, decidir si el primero es múltiplo del segundo -}
esMultiploDe :: Int -> Int -> Bool
esMultiploDe x y | mod x y == 0 = True
| mod y x == 0 = True
| otherwise = False
{- |digitoUnidades:
dado un número natural, extrae su dígito de las unidades -}
digitoUnidades :: Int -> Int
digitoUnidades x = mod x 10
{- |digitoDecenas:
dado un número natural, extrae su dígito de las decenas -}
digitoDecenas :: Int -> Int
digitoDecenas x = div (mod x 100) 10