Empezando con Haskell
Durante unos días he intentado comprender el paradigma de programación funcional en Haskell. Lo hice leyendo tutoriales y viendo screencasts, pero nada parece funcionar. Ahora, al aprender varios lenguajes imperativos/OO (como C, Java, PHP), los ejercicios han sido un buen camino a seguir. Pero como no sé realmente de qué es capaz Haskell y porque hay muchos conceptos nuevos para utilizar, no sé por dónde empezar.
Entonces, ¿cómo aprendiste Haskell? ¿Qué te hizo realmente "romper el hielo"? Además, ¿alguna buena idea para empezar a hacer ejercicios?
Voy a ordenar esta guía según el nivel de habilidad que tengas en Haskell, desde un principiante absoluto hasta un experto. Tenga en cuenta que este proceso llevará muchos meses (¿años?), por lo que es bastante largo.
Novato absoluto
En primer lugar, Haskell es capaz de cualquier cosa, con suficiente habilidad. Es muy rápido (en mi experiencia, solo detrás de C y C++) y puede usarse para cualquier cosa, desde simulaciones hasta servidores, guis y aplicaciones web.
Sin embargo, hay algunos problemas que son más fáciles de escribir para un principiante en Haskell que otros. Los problemas matemáticos y los programas de proceso de listas son buenos candidatos para esto, ya que sólo requieren los conocimientos más básicos de Haskell para poder escribir.
Algunas buenas guías para aprender los conceptos básicos de Haskell son el Tutorial Happy Learn Haskell y los primeros 6 capítulos de Learn You a Haskell for Great Good (o su adaptación de JupyterLab ). Mientras los lees, es una muy buena idea resolver también problemas simples con lo que sabes.
Otros dos buenos recursos son Programación en Haskell desde los primeros principios y Programación en Haskell . Ambos vienen con ejercicios para cada capítulo, por lo que tendrás pequeños problemas sencillos que combinen lo que has aprendido en las últimas páginas.
Una buena lista de problemas para probar es la página de problemas de Haskell 99 . Estos comienzan de manera muy básica y se vuelven más difíciles a medida que avanzas. Es una muy buena práctica hacer muchos de estos, ya que te permiten practicar tus habilidades en recursividad y funciones de orden superior. Recomendaría omitir cualquier problema que requiera aleatoriedad ya que es un poco más difícil en Haskell. Marque esta pregunta SO en caso de que desee probar sus soluciones con QuickCheck (consulte Intermedio a continuación).
Una vez que haya resuelto algunos de ellos, podrá continuar con algunos de los problemas del Proyecto Euler . Están ordenados según el número de personas que los han completado, lo que es un buen indicador de dificultad. Estos ponen a prueba tu lógica y Haskell más que los problemas anteriores, pero aún deberías poder resolver los primeros. Una gran ventaja que tiene Haskell con estos problemas es que los números enteros no tienen un tamaño limitado. Para resolver algunos de estos problemas, será útil haber leído también los capítulos 7 y 8 de Aprende Haskell.
Principiante
Después de eso, debería tener un buen manejo de la recursividad y las funciones de orden superior, por lo que sería un buen momento para comenzar a resolver algunos problemas más del mundo real. Un muy buen lugar para comenzar es Real World Haskell (libro en línea, también puede comprar una copia impresa). Encontré que los primeros capítulos se introdujeron demasiado rápido para alguien que nunca antes había hecho programación funcional/usado recursividad. Sin embargo, con la práctica que habrías tenido al resolver los problemas anteriores deberías encontrarlo perfectamente comprensible.
Resolver los problemas del libro es una excelente manera de aprender a gestionar abstracciones y construir componentes reutilizables en Haskell. Esto es vital para las personas acostumbradas a la programación orientada a objetos (oo), ya que los métodos de abstracción normales de oo (clases oo) no aparecen en Haskell (Haskell tiene clases de tipos, pero son muy diferentes a las clases oo, más bien como interfaces oo). ). No creo que sea una buena idea saltarse capítulos, ya que cada uno introduce muchas ideas nuevas que se utilizan en capítulos posteriores.
Después de un tiempo llegarás al capítulo 14, el temido capítulo de las mónadas (dum dum dummmm). Casi todos los que aprenden Haskell tienen problemas para comprender las mónadas, debido a lo abstracto que es el concepto. No puedo pensar en ningún concepto en otro lenguaje que sea tan abstracto como lo son las mónadas en la programación funcional. Monads permite unificar muchas ideas (como operaciones IO, cálculos que pueden fallar, análisis,...) bajo una sola idea. Así que no te desanimes si después de leer el capítulo sobre las mónadas no las entiendes realmente. Me resultó útil leer muchas explicaciones diferentes sobre las mónadas; cada uno da una nueva perspectiva sobre el problema. Aquí hay una muy buena lista de tutoriales de mónadas . Recomiendo ampliamente All About Monads , pero los demás también son buenos.
Además, lleva un tiempo asimilar los conceptos. Esto se logra con el uso, pero también con el tiempo. ¡Creo que a veces dormir sobre un problema ayuda más que cualquier otra cosa! Con el tiempo, la idea hará clic y te preguntarás por qué te costó entender un concepto que en realidad es increíblemente simple. Es increíble cuando esto sucede, y cuando sucede, es posible que Haskell sea tu lenguaje de programación imperativo favorito :)
Para asegurarte de que comprendes perfectamente el sistema de tipos de Haskell, debes intentar resolver 20 ejercicios de Haskell intermedios . Estos ejercicios utilizan nombres divertidos de funciones como "furry" y "banana" y te ayudan a tener una buena comprensión de algunos conceptos básicos de programación funcional si aún no los tienes. Bonita forma de pasar la velada con un montón de papeles cubiertos de flechas, unicornios, salchichas y plátanos peludos.
Intermedio
Una vez que comprenda Monads, creo que habrá realizado la transición de un programador principiante de Haskell a un haskeller intermedio. Entonces, ¿a dónde ir desde aquí? Lo primero que recomendaría (si aún no los ha aprendido al aprender mónadas) son los distintos tipos de mónadas, como Reader, Writer y State. Nuevamente, Real World Haskell y All about monads brindan una gran cobertura sobre esto. Para completar su entrenamiento de mónadas, es imprescindible aprender sobre los transformadores de mónadas. Estos le permiten combinar diferentes tipos de mónadas (como una mónada de lector y de estado) en una sola. Esto puede parecer inútil al principio, pero después de usarlos por un tiempo te preguntarás cómo vivías sin ellos.
Ahora puedes terminar el libro de Haskell del mundo real si quieres. Saltarse capítulos ahora realmente no importa, siempre y cuando tengas las mónadas controladas. Simplemente elige lo que te interesa.
Con el conocimiento que tendría ahora, debería poder usar la mayoría de los paquetes en Cabal (bueno, al menos los documentados...), así como la mayoría de las bibliotecas que vienen con Haskell. Una lista de bibliotecas interesantes para probar sería:
Parsec : para analizar programas y texto. Mucho mejor que usar expresiones regulares. Excelente documentación, también tiene un capítulo de Haskell del mundo real.
QuickCheck : un programa de prueba muy interesante. Lo que debes hacer es escribir un predicado que siempre debe ser verdadero (p. ej.
length (reverse lst) == length lst
). Luego, pasa el predicado QuickCheck y generará muchos valores aleatorios (en este caso, listas) y probará que el predicado sea verdadero para todos los resultados. Consulte también el manual en línea .HUnit : Pruebas unitarias en Haskell.
gtk2hs : el marco de interfaz gráfica de usuario más popular para Haskell, te permite escribir aplicaciones gtk.
happstack : un marco de desarrollo web para Haskell. No utiliza bases de datos, sino un almacén de tipos de datos. Documentos bastante buenos (otros marcos populares serían snap y yesod ).
Además, hay muchos conceptos (como el concepto de Mónada) que eventualmente deberías aprender. Esto será más fácil que aprender Mónadas la primera vez, ya que tu cerebro estará acostumbrado a lidiar con el nivel de abstracción involucrado. Una muy buena descripción general para aprender sobre estos conceptos de alto nivel y cómo encajan es Typeclassopedia .
Aplicativo: Una interfaz como Monads, pero menos potente. Toda Mónada es Aplicativa, pero no al revés. Esto es útil ya que hay algunos tipos que son aplicativos pero no son mónadas. Además, el código escrito con las funciones aplicativas suele ser más componible que escribir el código equivalente con las funciones Monad. Consulte Funtores, funtores aplicativos y monoides en la guía Aprenda a Haskell.
Plegable , Traversable : clases de tipos que abstraen muchas de las operaciones de las listas, de modo que las mismas funciones se puedan aplicar a otros tipos de contenedores. Consulte también la explicación de la wiki de Haskell .
Monoide : Un Monoide es un tipo que tiene un valor cero (o vacío) y una operación, anotada,
<>
que une dos Monoides, de modo quex <> mempty = mempty <> x = x
yx <> (y <> z) = (x <> y) <> z
. Éstas se denominan leyes de identidad y asociatividad. Muchos tipos son monoides, como los números, conmempty = 0
y<> = +
. Esto es útil en muchas situaciones.Flechas : las flechas son una forma de representar cálculos que toman una entrada y devuelven una salida. Una función es el tipo de flecha más básico, pero existen muchos otros tipos. La biblioteca también tiene muchas funciones muy útiles para manipular flechas; son muy útiles incluso si solo se usan con funciones antiguas de Haskell.
Matrices : las diversas matrices mutables/inmutables en Haskell.
ST Monad : te permite escribir código con un estado mutable que se ejecuta muy rápidamente, sin dejar de ser puro fuera de la mónada. Vea el vínculo para mas detalles.
FRP: Programación reactiva funcional, una forma nueva y experimental de escribir código que maneja eventos, activadores, entradas y salidas (como una interfaz gráfica de usuario). Aunque no sé mucho sobre esto. La charla de Paul Hudak sobre yampa es un buen comienzo.
Hay muchas características de lenguaje nuevas que deberías echarle un vistazo. Solo los enumeraré, puede encontrar mucha información sobre ellos en Google, el wikibook de Haskell , el sitio haskellwiki.org y la documentación de ghc .
- Clases de tipos multiparamétricos/dependencias funcionales
- Familias tipográficas
- Tipos existencialmente cuantificados
- Tipos fantasma
- GADTOS
- otros...
Gran parte de Haskell se basa en la teoría de categorías , por lo que es posible que desees investigar eso. Un buen punto de partida es la teoría de categorías para informáticos . Si no desea comprar el libro, el artículo relacionado del autor también es excelente.
Finalmente querrás aprender más sobre las diversas herramientas de Haskell. Éstas incluyen:
- ghc (y todas sus características)
- cabal : el sistema de paquetes Haskell
- darcs : un sistema de control de versiones distribuido escrito en Haskell, muy popular para los programas Haskell.
- eglefino : un generador automático de documentación de Haskell
Mientras aprende todas estas nuevas bibliotecas y conceptos, es muy útil escribir un proyecto de tamaño moderado en Haskell. Puede ser cualquier cosa (por ejemplo, un pequeño juego, un analizador de datos, un sitio web, un compilador ). Trabajar en esto le permitirá aplicar muchas de las cosas que está aprendiendo ahora. Permaneces en este nivel durante años (aquí es donde estoy yo).
Experto
Te llevará años llegar a esta etapa (¡hola desde 2009!), pero a partir de aquí supongo que empezarás a escribir artículos de doctorado, nuevas extensiones de ghc y a generar nuevas abstracciones.
Obteniendo ayuda
Finalmente, en cualquier etapa del aprendizaje, existen múltiples lugares para obtener información. Estos son:
- el canal irc #haskell
- las listas de correo . Vale la pena registrarse solo para leer las discusiones que tienen lugar; algunas son muy interesantes.
- otros lugares enumerados en la página de inicio de haskell.org
Conclusión
Bueno, esto resultó más largo de lo que esperaba... De todos modos, creo que es una muy buena idea dominar Haskell. Lleva mucho tiempo, pero eso se debe principalmente a que al hacerlo estás aprendiendo una forma de pensar completamente nueva. No es como aprender Ruby después de aprender Java, sino como aprender Java después de aprender C. Además, estoy descubriendo que mis habilidades de programación orientada a objetos han mejorado como resultado de aprender Haskell, ya que estoy viendo muchas formas nuevas de abstraer ideas.
¡Un colega mío tuvo una buena experiencia con Learn You a Haskell for Great Good! .
Tutorial dirigido a personas que tengan experiencia en lenguajes de programación imperativos pero que no hayan programado antes en un lenguaje funcional.
Y mira las respuestas aquí también.
Aquí tienes un buen libro que puedes leer en línea: Real World Haskell
La mayoría de los programas de Haskell que he realizado han sido para resolver problemas del Proyecto Euler .
Un consejo que leí no hace mucho fue que deberías tener un conjunto estándar de problemas simples que sepas resolver (en teoría) y luego, cada vez que intentes aprender un nuevo idioma, implementar esos problemas en ese idioma.
Disfruté viendo esta serie de 13 episodios sobre programación funcional usando Haskell.
Conferencias C9: Dr. Erik Meijer - Fundamentos de programación funcional: http://channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1/