es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Código estandarizado en la definición de un monad.

Desde la Propuesta Functor-Applicative-Monad, los Monads son una subclase de Applicative, que a su vez es una subclase de Functor. Matemáticamente hablando, esto parece ser una elección sensata y no tengo ningún problema con eso.

Sin embargo, lo que me irrita es que se requiere escribir las instancias Functor y Applicative incluso si las leyes correspondientes para fmap, pure y <*> ya están definidas por las leyes del monad de todas formas. De hecho, en la propuesta mencionada anteriormente, ellos lo escriben ellos mismos: “Simplemente puedes derivar estas instancias a partir del Monad agregando el siguiente código”:

import Control.Applicative (Applicative(..))
import Control.Monad       (liftM, ap)

instance Functor m where
    fmap = liftM

instance Applicative m where
    pure  = {- mueve la definición de <code>return</code> desde la instancia <code>Monad</code> aquí -}
    (<*>) = ap

Y en la mayoría de los tutoriales, simplemente verás la igualdad pure=return y la gente continúa definiendo return en la instancia de Monad como antes. Por lo tanto, en efecto, se agregaron 10 líneas de código de boilerplate para todos aquellos que simplemente quieren definir una instancia de Monad.

En matemáticas, usualmente tampoco se opera de esta manera. Por ejemplo, al definir las leyes de composición para un cierto anillo, normalmente no se recuerda explícitamente nuevamente que los anillos son instancias especiales de grupos abelianos bajo la adición, que a su vez son instancias especiales de grupos. Esto es claro por definición de todas formas.

Por lo tanto, mi pregunta es: Aunque está bien que los Monads sean una subclase de Applicative, que a su vez es una subclase de Functor, ¿esto no podría simplemente “suceder en segundo plano” en el sentido de que el compilador inserte el código boilerplate en lugar del programador?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en Haskell, puedo entender la frustración de tener que escribir las instancias de Functor y Applicative a pesar de que sus leyes ya están determinadas por las leyes de Monad. Si bien matemáticamente tiene sentido que los Monads sean una subclase de Applicative y Functor, sería bueno si el compilador pudiera manejar el código repetitivo para el programador.

    Sin embargo, vale la pena señalar que Haskell es un lenguaje que valora la explicitud y la claridad. Al requerir que el programador escriba las instancias de Functor y Applicative, se refuerza la comprensión de cómo estos conceptos encajan y cómo se implementan dentro de un Monad. Aunque pueda parecer un trabajo adicional, puede ayudar a prevenir posibles errores en el código.

    Además, Haskell es un lenguaje que a menudo prioriza la capacidad de personalizar y optimizar el código para casos de uso específicos. Permitir al programador definir explícitamente estas instancias les da la capacidad de adaptar el código a sus necesidades específicas.

    En resumen, aunque pueda ser frustrante escribir el código repetitivo de las instancias de Functor y Applicative dentro de un Monad, en última instancia refuerza la comprensión y permite la personalización y optimización del código.

Comments are closed.