23 dic. 2007

Mas sobre Tipos

Ya se explicó como crear tipos de datos algebraicos en Haskell, éstos pueden ser finitos o infinitos (para ésto usamos la recursión), ¿pero cómo podemos usar esos tipos de datos?, ¿se pueden definir funciones cuyo dominio o codominio sean esos tipos de datos?, ejemplos:

usando el tipo de datos:

data Formula = Y Formula Formula | NO Formula | T| Var Integer


-- Función que recibe un entero y devuelve una formula,

creaVar i = Var i

-- Función que aplica "una" ley parecida a la de De Morgan



casideMorgan (NO (Y f1 f2)) = Y (NO f1) (NO f2)


El tipo de la primer función es: Integer -> Formula; es decir toma un entero y regresa una Formula
El tipo de la segunda función es: Formula -> Formula, es decir toma una Formula y regresa otra Formula

Show

La clase Show es importante cuando se define un tipo de dato en Haskell, ya que ésta es la que "dice" como se mostrara ese tipo de dato en la salida; si intentamos usar el tipo de dato Formula, tal cual lo tenemos, el interprete de Haskell (si se usa hugs) se "quejara" , por ejemplo si ejecutamos en hugs

Main> casideMorgan (NO (Y (Var 1) (Var 2)))
ERROR - Cannot find "show" function for:
*** Expression : deMorgan (NO (Y (Var 1) (Var 2)))
*** Of type : Formula

El interprete se queja, ya que no sabe como mostrar el resultado, este error no indica que este mal la definición del tipo de dato o la definición de la función que la usa, este error indica que no se sabe como mostrar el resultado; Existen dos formas de arreglar esto

  • Agregar deriving (Show)
Si modificamos la definición del tipo de dato Formula de la siguiente manera

data Formula = Y Formula Formula | NO Formula | True| Var Integer
deriving (Show)

y ejecutamos nuevamente:

Main>casideMorgan (NO (Y (Var 1) (Var 2)))

Y (NO (Var 1)) (NO (Var 2))


La salida es correcta!!, y el horroroso "error" anterior ha desaparecido, sin embargo, la salida no tiene un aspecto muy elegante o fácil de leer

  • Otra forma es: Definiendo la función show para nuestro tipo de dato.
instance Show Formula where show=showFormula

showFormula T = "T"
showFormula (Var i) = "x"++ show i
showFormula (NO a) = "¬"++ show a
showFormula (Y a b) = show a ++ " Y " ++ show b


ejecutamos nuestro ejemplo de nuevo

Main> casideMorgan (NO (Y (Var 1) (Var 2)))
¬x1 Y ¬x2

La salida es mas estética, y quizá más fácil de leer.

Para esta opción no se debe poner deriving (Show) a la definición del tipo de dato

No hay comentarios:

ga