2012-02-10 9 views
7

He estado escribiendo una base de código creciente en Haskell. Mi problema es que he agregado firmas de tipos a las funciones en función de lo que GHCI me dice que deben ser.¿Cómo mantengo flexible la escritura fuerte de Haskell?

El problema ahora es que tengo una base de código en crecimiento, tan pronto como cambio una cosa, mi código se rompe por todas partes y me consume el rastreo de todos los problemas.

¿Los tipos derivados de cargar un módulo en ghci son demasiado específicos? ¿Cómo decido qué tipo o tipo de clases usar en mis firmas para aprovechar el poder de la mecanografía fuerte con cierta flexibilidad? (es decir, ¿no pasar una hora propagando cambios menores?).

+4

Eso parece un poco extraño. ¿Qué estás haciendo exactamente que rompe todo el código? ¿Estás cambiando tus tipos continuamente? Normalmente uno se fijaría en un diseño para sus tipos después de un tiempo (o incluso al principio), y la mayor parte del trabajo estaría en el resto del código (lo que en un Haskell correctamente escrito debería ser increíblemente independiente). Tenga en cuenta también que si agrega constructores a su tipo, no es sorprendente que el código que maneja ese tipo se rompe y el compilador es útil para señalar problemas potenciales, aunque los genéricos pueden ayudar si no se debe romper el código. .. – Jedai

+5

Quizás necesite hacer algunos sinónimos tipo o definiciones de tipo para que sus cambios puedan ser localizados en un solo lugar. – augustss

+2

¿Puedes dar un ejemplo de lo que intentas lograr y cómo esperas que se comporte? – ondra

Respuesta

7

El problema ahora es que tengo una base de código en crecimiento, tan pronto como cambio una cosa, mi código se rompe por todas partes y me consume el rastreo de todos los problemas.

Esto es en realidad anuncian como una característica en Yesod (un framework web Haskell). Supongamos que yo he especificado la siguiente especificación de enrutamiento:

/blog/#String   BlogR GET 

y decido que quiero cambiarlo a

/blog/#Date/#String BlogR GET 

Tan pronto como hago este cambio en las rutas, el compilador dime todas partes que He roto mi código Me veré obligado a actualizar la función getBlogR - cambiando su tipo de entrada para que también acepte un Date. También me veré obligado a actualizar cualquier lugar donde use URL seguras de tipo en mis plantillas, que se vería como @{BlogR (slug p)} ->@{BlogR (date p) (slug p)}.

Ésta se considera una buena cosa , porque el tipo de corrector es ayudar a encontrar problemas introducidos por los cambios realizados.


Ahora, con respecto a ghci.

ghci> let shew = show 
ghci> :t shew 
shew ::() -> String 
ghci> :t show 
show :: Show a => a -> String 

A veces es cierto que ghci elige los valores predeterminados molestos. Esto, sin embargo, puede ser aliviado.

ghci> :set -XNoMonomorphismRestriction 
ghci> let shew = show 
ghci> :t shew 
shew :: Show a => a -> String 

Durante el uso de ghci a descubrir el tipo de función es ideal para principiantes, yo no recomendaría confiando en ghci. Aprenda qué significan las firmas de tipo, y cómo descubrirlas usted mismo. De hecho, comience a escribir una función escribiendo primero la firma de tipo que pretende que tenga. Solo se necesita una pequeña inversión de tiempo para aprender esta habilidad, y es una gran ayuda programar cuando puede usar el sistema de tipos de Haskell para su ventaja.

+1

Habiendo dicho todo esto, la respuesta real a su pregunta es probablemente lo que augustss sugirió: escriba sinónimos y escriba definiciones para limpiar su código. –

+0

¡Impresionante! Mi problema es que el sistema de tipos es tan complejo que para un principiante hago una mejor aproximación a la firma, y ​​acabo preguntando ghci. (Mis problemas actuales son con las clases de tipos de números). – Toymakerii

+0

¿Hay alguna manera de decirle a GHCI o a un programa de borrado que compare mis definiciones codificadas con una mejor versión más genérica? – Toymakerii