Funciones
Para definir una función se debe indicar su signatura y la ecuación que la define. La signatura se compone del nombre de la función, el conjunto dominio y el codominio.
cuad :: R -> R
cuad(x) = x * x
inverso :: Rno0 -> R
inverso(x) = 1 / x
areaTriangulo :: R X R -> R
areaTriangulo(base, altura) = (base * altura) / 2
pi :: () -> R
pi() = 3.1416
areaCirculo :: R -> R
areaCirculo(r) = pi() * cuad(r)
Por ejemplo, la signatura de la función cuad de la Figura 2 es cuad :: R −>R, indicando que la función cuad va de reales a reales. Notar que en inverso utilizamos como dominio el conjunto Rno0 definido en la Figura 1. En la signatura de la función areaTria podemos ver que para representar funciones de múltiples variables (en este caso dos reales) utilizamos tuplas como dominio. También es posible definir la operación nularia, que va del producto vacío a A, o sea () −> A lo que permite definir y usar constantes, como Pi en la Figura 2.
La ecuación se define dando el nombre de la función, las variables independientes (es decir, parámetros) y el cuerpo de la función. El cuerpo de una función se compone de una expresión o de una lista de expresiones.
En el caso de la función cuad, definida en la Figura 2, la variable independiente es x y el cuerpo de la función es la expresión x * x. En el caso de la Figura 3, el cuerpo de las funciones abs y max es una lista de dos expresiones, que representan la definición por casos de las definiciones de las funciones matemáticas. Por ejemplo la definición de abs se lee así: abs(x) es x si x >= 0 si no es -x. Observar que la definición por casos (en matemática) o por expresiones (en MateFun) simula la sentencia if cond then resultado1 else reultado2.
abs :: R -> R
abs(x) = x si x >= 0
{ -x
max :: R X R -> R
max(x,y) = x si x >= y
{ y
dias :: Mes -> R
dias(m) = 31 si m == Enero
{ 28 si m == Febrero
{ 31 si m == Marzo
{ 30 si m == Abril
{ 31 si m == Mayo
{ 30 si m == Junio
{ 31 si m == Julio
{ 31 si m == Agosto
{ 30 si m == Setiembre
{ 31 si m == Octubre
{ 30 si m == Noviembre
{ 31
¿Cómo se ejecuta una definición de función? Es decir, ¿cómo se obtiene el resultado?
En el caso de que el cuerpo sea una lista de expresiones, se ejecuta cada expresión empezando por la primera. Cuando se encuentra una
condición para la que se cumple la condición, se devuelve el resultado correspondiente y la ejecución finaliza.
La lista de expresiones debe contener al final o al principio, una expresión que devuelva un resultado sin condiciones, para que la
ejecución siempre finalice y para asegurar que las funciones sean totales en el dominio. A modo de ejemplo, a continuación se definen
recursivamente la función potencia que dados a y b naturales devuelve a^b y la función factorial que devuelve el factorial de un natural x
y se muestran los pasos de sus ejecuciones. Observar que el producto por 1 se repite dado que factorial de define para N.
potencia :: N X N -> N
potencia (a,b) = 0 si a == 0
{ 1 si b == 0
{ a * potencia(a,b-1)
{- potencia (2,3) = 2 * potencia (2, 2) porque ni a ni b son 0
= 2 * 2 * potencia(2,1) idem
= 2 * 2 * 2 * potencia(2, 0) idem
= 2 * 2 * 2 * 1 porque b = 0
-}
factorial :: N -> N
factorial (x) = x * factorial (x -1) si x > 0
{ 1
{- factorial (4) = 4 * factorial (3) porque 4 > 0
= 4 * 3 * factorial (2) ídem
= 4 * 3 * 2 * factorial (1) idem
= 4 * 3 * 2 * 1 * factorial (0) 4 * 3 * 2 * 1 * 1 porque x = 0
-}
Un valor literal puede ser un elemento de un conjunto definido por enumeración, un número, un color, una figura vacía o una secuencia vacía.
Los operadores son los operadores aritméticos (definidos para N, Z, R y todos sus sub-conjuntos) ("+", "−", "∗", "/", " "), Son también operadores la proyección de una n-upla para un índice i y el que inserta un elemento al inicio de una secuencia (función constructora de secuencias). Se ilustran con ejemplos en la Figura 4:
1 : [3,2]
[1,3,2]
(1,0,3)!2
0
f :: R -> R
f(x) = x * x * x
g :: R -> R
g(x) = x - 1
h :: R -> R
h(x) = g(f(x))
Observar que la aplicación de una función a un argumento es asimismo una expresión, que puede ser usada por ejemplo en la definición de otra función, como en el caso de la función h en la Figura 4.
Además de los operadores aritméticos, el lenguaje provee de funciones primitivas, por ejemplo para hallar el seno (sen), coseno (cos) y raíz cuadrada (raizcuad) de un número. La lista de las funciones primitivas puede obtenerse ejecutando el comando ?funs en la parte derecha del IDE de MateFun.
Definiciones locales:
Una definición local define una variable dentro de la definición de una función. En el primer ejemplo abajo, se define una función raices para hallar las raices reales de una ecuación de segundo grado, definiendo delta localmente, como suele hacerse en matemática (para simplificar el primer ejemplo, se supone que la ecuación tiene raíces reales). En el segundo ejemplo se define divEntera que toma dos naturales, el segundo distinto de cero, y devuelve cociente y resto de la división entera del primero por el segundo.
raices :: R X R X R -> R X R
raices(a,b,c) = ((-b + delta)/(2*a),
(-b - delta)/(2*a))
donde delta = raizcuad(b^2 - 4*a*c)
divEntera :: N X Nno0 -> N X N
divEntera(a,b) = (c,r)
donde c = div(a,b)
r = mod(a,b)