title | author |
---|---|
Laboratorio de Funcional |
Ezequiel Marin, Alexis Ortiz, Bruno Lopez Storani |
La consigna del laboratorio está en https://tinyurl.com/funcional-2024-famaf
Pueden usar esta checklist para indicar el avance.
- Haskell instalado y testeos provistos funcionando. (En Install.md están las instrucciones para instalar.)
- Módulo
Dibujo.hs
con el tipoDibujo
y combinadores. Puntos 1 a 3 de la consigna. - Definición de funciones (esquemas) para la manipulación de dibujos.
- Módulo
Pred.hs
. Punto extra si definen predicados para transformaciones innecesarias (por ejemplo, espejar dos veces es la identidad).
- Módulo
Interp.hs
.
- El dibujo de
Dibujos/Feo.hs
se ve lindo. - Módulo
Dibujos/Grilla.hs
. - Módulo
Dibujos/Escher.hs
. - Listado de dibujos en
Main.hs
.
- Tests para
Dibujo.hs
. - Tests para
Pred.hs
.
Si bien al principio nos costo un poco acostumbrarnos a la sintaxis y a la forma de programar en Haskell, una vez que le agarramos la mano nos resulto muy comodo y sencillo. Fue muy interesante este desafio ya que nos permitio entender y asimilar el concepto de paradigma funcional, con la que no habiamos trabajado con anterioridad.
La idea del laboratorio nos parecio muy interesante y creativa. Fue interesante aprender a representar dibujos de manera abstracta y luego interpretarlos de manera grafica. La idea de separar las funcionalidades en modulos nos parecio muy acertada ya que nos permitio trabajar de manera mas organizada y eficiente.
Destacamos la idea de la interpretacion grafica luego de haber definido los dibujos de manera abstracta, ya que nos permitio ver de manera visual el resultado de nuestro trabajo.
Tuvimos bastantes dificultades, sobre todo adaptandonos a la sintaxis de Haskell y a la forma de programar en este lenguaje. Lo que mas nos complico fue entender como debiamos interpretar vectorialmente los dibujos, y como debiamos definir las funciones para manipularlos.
Tambien al principio nos costo mucho la configuracion del entorno de trabajo, ya que cabal nos generaba muchos problemas y no podiamos instalar las dependencias necesarias.
Nuestra dinamica de trabajo fue muy buena, ya que pudimos organizarnos y dividir las tareas de manera equitativa.
Generalmente trabajabamos juntos, utilizando la herramienta de Live Share
de Visual Studio Code, lo que nos permitio trabajar en tiempo real y compartir el codigo de manera sencilla y tambien para comunicarnos utilizabamos Discord
.
Cuando realizabamos cambios, lo documentabamos en un documento de Notion
para que el otro integrante pueda entender los cambios realizados.
Al responder tranformar cada pregunta en una subsección para que sea más fácil de leer.
- 3.1 ¿Por qué están separadas las funcionalidades en los módulos indicados?
- 3.2 ¿Por qué las figuras básicas no están incluidas en la definición del lenguaje, y en vez de eso, es un parámetro del tipo?
- 3.3 ¿Qué ventaja tiene utilizar una función de
fold
sobre hacer pattern-matching directo?
- Claridad y organización: Cada módulo tiene su tarea y propósito, esto facilita la comprensión del código.
- Mantenimiento más sencillo: Ya que los modulos son independientes entre si, cuando se realizan cambios o se corrigen errores es mas facil indentificar la parte especifica del codigo que necesita ser corregida.
- Mejor colaboración: Con esta separacion de responsabilidades de cada modulo pudimos separar las tareas de cada integrante.
3.2 ¿Por qué las figuras básicas no están incluidas en la definición del lenguaje, y en vez de eso, es un parámetro del tipo?
No sabemos a priori qué figuras básicas tendremos, y por eso el tipo Dibujo debe ser polimórfico. Una figura basica podria ser cualquier letra del abecedario, un elipse, o un octagono, cada uno con una implementacion diferente.
La ventaja de fold
es que se puede crear un codigo mucho mas sencillo y comprensible. Por ejemplo, la utilizamos en interp.hs
en la funcion interp
de esta manera:
interp :: Output a -> Output (Dibujo a)
interp f = foldDib f rot esp r45 api jun sup
Con foldDib
logramos hacer la funcion en una sola linea. En cambio al hacer pattern-matching hubiera resultado asi:
interp :: Output a -> Output (Dibujo a)
interp f Vacia = simple blank
interp f (Basica a) = f a
interp f (Rot90 a) = rot (interp f a)
interp f (Rot45 a) = rot45 (interp f a)
interp f (Espejar a) = esp (interp f a)
interp f (Apilar x y a b) = api x y (interp f a) (interp f b)
interp f (Juntar x y a b) = jun x y (interp f a) (interp f b)
interp f (Encimar a b) = ov (interp f a) (interp f b)
Tambien utilizamos foldDib
muchas veces en el modulo pred.hs
.
En resumen, utilizando foldib logramos mayor legibilidad y simplicidad en el codigo, ademas de la reutilizacion de codigo.
Los archivos Pred.hs y TestPred.hs cumplen roles diferentes:
-
Pred.hs contiene la definicion de funciones (predicados) que realizan ciertas operaciones o verificaciones en nuestros datos.
-
TestPred.hs contiene tests que verifican que las funciones en Pred.hs funcionen correctamente. Cada test en TestPred.hs usa una funcion de Pred.hs, le pasa algunos valores y verifica que el resultado sea el que nosotros queremos.
Basicamente, Pred.hs define el comportamiento, y TestPred.hs verifica ese comportamiento.
- Dibujos adicionales:
Agregamos un dibujo adicional llamado
Dibujos/Antropia.hs
. Este dibujito es una sucesion recursiva de lineas que forman un efecto visual cuando se acerca y se aleja.