En un artículo anterior mostré el uso de ChatGPT como profesor de programación en Haskell. Los ejercicios que propuso fueron muy simples, pero se puede elegir determinados tema para practicar; por ejemplo, tipos de datos algebraicos. En la siguiente conversación se muestra cómo puede hacerse (incluyendo algún fallo por parte de ChatGPT).
Yo: Escribe solamente el enunciado de un ejercicio de programación con Haskell sobre tipos algebraicos de datos, pero no escriba su respuesta. Espera que yo escriba la respuesta y corrígela.
ChatGPT: Aquí está el enunciado del ejercicio:
Escribe una definición de tipo algebraico de datos en Haskell para modelar una lista polimórfica y luego implementa una función que tome dos listas y las concatene en una sola lista. Asegúrate de manejar correctamente los casos base y recursivos.
Yo:
|
data Lista a = Vacia | Cons a (Lista a) deriving (Show, Eq) concatenacion :: Lista a -> Lista a -> Lista a concatenacion Vacia ys = ys concatenacion (Cons x xs) ys = Cons x (concatenacion xs ys) |
ChatGPT: ¡Correcto! Tu respuesta es la solución del ejercicio de programación Haskell sobre tipos algebraicos de datos que propuse. Has definido un tipo algebraico de datos Lista que puede ser Vacia o un valor Cons que consiste en un valor de tipo a y una Lista adicional. Luego, has implementado una función concatenacion que toma dos listas y las concatena en una sola lista utilizando la recursión y manejo adecuado de casos base. ¡Bien hecho!
Yo: Otro.
ChatGPT: ¡Por supuesto! Aquí está el enunciado del ejercicio:
Define un tipo algebraico de datos en Haskell para modelar una expresión aritmética que puede ser una suma, una resta, un producto o una división de dos expresiones aritméticas. Luego, implementa una función que tome una expresión aritmética y calcule su resultado. Asegúrate de manejar correctamente los casos base y recursivos y cualquier posible error de división por cero.
Yo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
data Expresion = Suma Expresion Expresion | Resta Expresion Expresion | Producto Expresion Expresion | Division Expresion Expresion | Numero Float deriving Show valor :: Expresion -> Maybe Float valor (Numero x) = Just x valor (Suma x y) = (+) <$> valor x <*> valor y valor (Resta x y) = (-) <$> valor x <*> valor y valor (Producto x y) = (*) <$> valor x <*> valor y valor (Division x y) = do y' <- valor y if y' == 0 then Nothing else (/) <$> valor x <*> Just y' |
ChatGPT: ¡Excelente trabajo! Tu solución es correcta. Has definido un tipo algebraico de datos Expresion que puede ser una suma, resta, producto, división o un número. Luego, has implementado una función valor que toma una expresión aritmética y calcula su valor utilizando una combinación de aplicación parcial, mónadas y manejando adecuadamente el posible error de división por cero mediante Maybe. ¡Muy bien hecho!
Yo: Otro.
ChatGPT: ¡Claro! Aquí está el enunciado del ejercicio:
Define un tipo algebraico de datos en Haskell para modelar un árbol binario que puede ser un árbol vacío o un nodo con un valor y dos sub-árboles. Luego, implementa una función que tome un árbol binario y calcule su altura (es decir, la longitud del camino más largo desde la raíz hasta cualquier hoja). Asegúrate de manejar correctamente los casos base y recursivos.
Yo:
|
data Arbol a = Vacio | Nodo a (Arbol a) (Arbol a) deriving (Show) altura :: Arbol a -> Int altura Vacio = 0 altura (Nodo _ izquierda derecha) = max (altura izquierda) (altura derecha) |
ChatGPT: ¡Correcto! Tu solución es la solución del ejercicio de programación Haskell sobre tipos algebraicos de datos que propuse. Has definido un tipo algebraico de datos Arbol que puede ser un Vacio o un Nodo que contiene un valor y dos sub-árboles. Luego, has implementado una función altura que toma un árbol binario y calcula su altura utilizando la recursión y manejando adecuadamente los casos base. ¡Muy bien hecho!
Yo: ¿No falta sumar 1 en el caso recursivo?
ChatGPT: Tienes razón, ¡gracias por señalarlo! En el caso recursivo de la función altura, debemos sumar 1 al máximo de las alturas de los dos sub-árboles, ya que el nodo actual también cuenta como una unidad de altura. Entonces, la solución correcta sería la siguiente:
|
altura :: Arbol a -> Int altura Vacio = 0 altura (Nodo _ izquierda derecha) = 1 + max (altura izquierda) (altura derecha) |
De esta manera, la función altura calcula correctamente la altura de un árbol binario. ¡Gracias por la corrección!