==== Algunas herramientas para el laboratorio ====
En algunos de los proyectos necesitaremos consultar sobre la
definición de algunas clases, o sobre la existencia de alguna función
(definida en el preludio); también puede ser útil poder corrobar que
el tipo de una función es el que nosotros esperamos.
A continuación, recordamos ciertas formas de obtener el tipo de
información que comentamos en el párrafo anterior. Para ello vamos a
repasar algunas otras cosas relativas a Haskell.
Hay varios intérpretes para Haskell, al día de hoy el más difundido es
GHCi (que es parte del compilador GHC); también podemos usar Hugs,
pero a los fines prácticos de esta materia no hay ninguna diferencia
entre ambos.
Para instalar GHCi en nuestra máquina podemos descargar la
[[http://hackage.haskell.org/platform/ | plataforma Haskell]], que
además del intérprete y del compilador contiene muchas librerías (una
librería-mal traducción para el término library- es un conjunto de
módulos con funciones relacionadas con la solución de problemas
relacionados) y otros programas que facilitan el desarrollo de
programas con Haskell (por ejemplo, cabal es un programa que nos
permite buscar y descargar nuevas librerías, y actualizar las
versiones de las librerías que están instaladas).
Por cierto, si nuestro sistema operativo es Linux, podemos tener
una mejor experiencia si usamos el manejador de paquetes de
nuestra distribución.
== Usar el intérprete para averiguar cosas ==
Tanto en Hugs como en GHCi podemos conocer la definición de una clase
y los tipos que forman parte de la misma :
Hugs> :i Ord
...
Los puntos suspensivos los usamos para no mostrar la salida que obtenemos
de un comando cuando la misma es muy extensa.
También podemos usar :i para conocer dónde está definida
una función:
Hugs> :i min
...
Para averiguar el tipo de una expresión podemos usar:
Hugs> :t expresion
== Cómo interpretar un error al cargar un archivo ==
Supongamos que tenemos el archivo Min.hs
minimo :: [a] -> a
minimo [] = error ""
minimo [x] = x
minimo (x:y:xs) = min x (minimo (y:xs))
Y lo cargamos en Hugs
Hugs> :l Min.hs
ERROR "Min.hs":2 - Cannot justify constraints in explicitly typed binding
*** Expression : minimo
*** Type : [a] -> a
*** Given context : ()
*** Constraints : Ord a
Hugs> :q
[Leaving Hugs]
El número que aparece luego del nombre del archivo es el número
de línea donde esta el error; en este caso el error está en la
definición de la función minimo. Luego se nos indica el error en
sí; en este caso vemos que necesitamos más restricciones sobre
el tipo que las que pusimos.
Por último, se nos informa las restricciones que nosotros pusimos
y las que nos hubieran hecho falta.
El mismo error en GHCi es reportado de manera diferente:
Prelude > :l a.hs
/home/miguel/work/facu/algo1-2010/notes/a.hs:4:18:
Could not deduce (Ord a) from the context ()
arising from a use of `min'
at a.hs:4:18-38
Possible fix:
add (Ord a) to the context of the type signature for `minimo'
In the expression: min x (minimo (y : xs))
In the definition of `minimo':
minimo (x : y : xs) = min x (minimo (y : xs))
Failed, modules loaded: none.
Prelude>
Aquí tenemos más información; pues se nos señala explícitamente
por qué necesitamos agregar la restricción "Ord a"; e incluso
se nos sugiere que podemos corregir este error agregando esa
restricción.
== Conocer qué hace una función ==
Para saber qué hace una función no tenemos un método desde Hugs
o GHCi; en cambio, debemos consultar o bien el reporte de Haskell,
o bien podemos utilizar Hackage.
El reporte de Haskell es donde se define la sintaxis de los programas
Haskell y una semántica para los mismos (análogo al capítulo 8, //El modelo
computacional// del libro). En este reporte está definido el llamado
preludio (Prelude) que incluye algunas clases, tipos y funciones predefinidas.
Las clases y los tipos predefinidos de Haskell se encuentran
documentados en el [[
http://www.haskell.org/onlinereport/haskell2010/haskellch6.html | capítulo 6]].En el
[[http://www.haskell.org/onlinereport/haskell2010/haskellch9.html|
capítulo 9]] del reporte está la definición completa del Prelude.
También podemos consultar el contenido del Preludio usando la
documentación del mismo en
[[http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Prelude.html|Hackage]]
(que es un sitio donde se encuentra la documentación, entre otras
cosas, de muchas librerías de Haskell).
Tal vez sea díficil encontrar la definición de una clase, tipo o
función en particular. Para ello, puede ser más útil usar
[[http://haskell.org/hoogle/ | Hoogle]], que es un buscador de
definiciones de Haskell.
== Usando Hoogle ==
La forma en que vamos a utilizar Hoogle, por el momento, es consultando
definiciones en el preludio. Para ello, ingresamos en la caja de texto,
ponemos el nombre de la definición que nos interesa seguido de " +Prelude",
por ejemplo:
map +Prelude
Los resultados muestran muchas funciones que corresponden (puede ser
que haya más de las que querramos) con nuestra búsqueda. La segunda
parte de nuestra búsqueda (" +Prelude") hace que todos los resultados
estén definidos en el preludio.
Si cliqueamos en el enlace de un ítem del resultado de la búsqueda,
iremos a parar a la documentación de la función tal como se encuentra
en Hackage. En caso que la documentación no sea suficiente, podemos
consultar la definición de la función (o el tipo) cliqueando en el
enlace "Source" (código fuente) que está a la derecha de la signatura.
Otra forma de usar Hoogle es especificando el tipo de la función
que necesitamos, por ejemplo, podríamos saber si existe una función
con tipo "Ord a => a -> a -> a" definida en el preludio, para ello
haríamos la siguiente consulta:
Ord a => a -> a -> a +Prelude
Como antes, Hoogle supone que nosotros podemos estar interesados en
más cosas que las pusimos explícitamente. Por ello, no nos debe
sorprender que obtengamos resultados inesperados; en general, lo
esperado aparecerá entre los primeros resultados.