aboutsummaryrefslogtreecommitdiff
path: root/pia
diff options
context:
space:
mode:
authorJuan Marin Noguera <juan@mnpi.eu>2022-11-16 12:08:19 +0100
committerJuan Marin Noguera <juan@mnpi.eu>2022-12-04 13:20:36 +0100
commit3e9874f10d8a4aa42d048f2f387b7f35942e2c4f (patch)
treee2414e069b2799a0e75ed32fd94ece6405d7f3a5 /pia
parentff62f76ee6a763e275a6e05eb87d842d843fc374 (diff)
PIA tema 5
Diffstat (limited to 'pia')
-rw-r--r--pia/n.lyx14
-rw-r--r--pia/n4.lyx1861
-rw-r--r--pia/n5.lyx1876
3 files changed, 3513 insertions, 238 deletions
diff --git a/pia/n.lyx b/pia/n.lyx
index db09664..309e23c 100644
--- a/pia/n.lyx
+++ b/pia/n.lyx
@@ -271,5 +271,19 @@ filename "n4.lyx"
\end_layout
+\begin_layout Chapter
+El preludio estándar
+\end_layout
+
+\begin_layout Standard
+\begin_inset CommandInset include
+LatexCommand input
+filename "n5.lyx"
+
+\end_inset
+
+
+\end_layout
+
\end_body
\end_document
diff --git a/pia/n4.lyx b/pia/n4.lyx
index f64f732..409ac7c 100644
--- a/pia/n4.lyx
+++ b/pia/n4.lyx
@@ -382,7 +382,7 @@ Las variables pueden estar en espacios de nombres jerárquicos:
status open
\begin_layout Plain Layout
-tyvar=varid, tycon=tycls=conid, modid=qconid, qtycon=qtycls=qvarid
+tyvar=varid, tycon=tycls=conid, modid=qtycon=qtycls=qconid
\end_layout
\end_inset
@@ -629,13 +629,6 @@ lexer
los inserte como sigue:
\end_layout
-\begin_layout Standard
-\begin_inset Separator plain
-\end_inset
-
-
-\end_layout
-
\begin_layout Enumerate
Tras un
\family typewriter
@@ -812,7 +805,21 @@ nombre
valor
\family default
\emph default
- describen la gramática libre de contexto de Haskell en ABNF.
+ describen la gramática libre de contexto de Haskell en ABNF, con la extensión
+ de que
+\family typewriter
+!
+\emph on
+x
+\family default
+\emph default
+ indica que el siguiente elemento no debe tener forma
+\family typewriter
+\emph on
+x
+\family default
+\emph default
+.
Cada cadena entre comillas representa un sólo lexema y entre dos lexemas
puede haber espacio.
Esta gramática tiene ambigüedades que se resuelven haciendo las frases
@@ -924,6 +931,16 @@ operaciones primitivas
\series bold
preludios
\series default
+, por defecto el
+\series bold
+preludio estándar
+\series default
+, el módulo
+\family typewriter
+\lang english
+Prelude
+\family default
+\lang spanish
.
\end_layout
@@ -974,6 +991,137 @@ varop = varsym /
\end_layout
+\begin_layout Plain Layout
+
+con = conid /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ consym
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+conop = consym /
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+ conid
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+qvar = qvarid /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ qvarsym
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+qvarop = qvarsym /
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+ qvarid
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+qcon = qconid /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ gconsym
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+qconop = gconsym /
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+ qconid
+\begin_inset Quotes cld
+\end_inset
+
+`
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+gconsym = qconsym
+\end_layout
+
\end_inset
@@ -998,29 +1146,6 @@ s y una función con nombre normal como operador poniéndola entre comillas
Se pueden definir nuevos operadores.
\end_layout
-\begin_layout Standard
-La
-\series bold
-evaluación ansiosa
-\series default
- o
-\series bold
-llamada por valor
-\series default
- es como el orden aplicativo pero sin evaluar en el interior de abstracciones,
- y la
-\series bold
-evaluación perezosa
-\series default
- o
-\series bold
-llamada por nombre
-\series default
- es como el orden normal pero sin evaluar en el interior de abstracciones.
- Haskell usa evaluación perezosa, que al contrario que la ansiosa garantiza
- la terminación si la expresión es normalizable.
-\end_layout
-
\begin_layout Section
Tipos
\end_layout
@@ -1036,6 +1161,7 @@ valor indefinido
correspondiente a las expresiones de ese tipo cuya evaluación no termina,
aunque también se usa para notificar errores.
+
\end_layout
\begin_layout Standard
@@ -1071,35 +1197,11 @@ atype = gtycon / varid /
\begin_inset Quotes cld
\end_inset
- type *(
-\begin_inset Quotes cld
-\end_inset
-
-,
-\begin_inset Quotes crd
-\end_inset
-
- type)
-\begin_inset Quotes cld
-\end_inset
-
-)
-\begin_inset Quotes crd
-\end_inset
-
- /
-\begin_inset Quotes cld
-\end_inset
-
-[
-\begin_inset Quotes cld
-\end_inset
-
type
\begin_inset Quotes cld
\end_inset
-]
+)
\begin_inset Quotes crd
\end_inset
@@ -1108,44 +1210,21 @@ atype = gtycon / varid /
\begin_layout Plain Layout
-gtycon = qtycon /
-\begin_inset Quotes cld
-\end_inset
-
-(
-\begin_inset Quotes cld
-\end_inset
-
-
-\begin_inset Quotes cld
-\end_inset
-
-)
-\begin_inset Quotes crd
-\end_inset
-
- /
-\begin_inset Quotes cld
-\end_inset
-
-[
-\begin_inset Quotes cld
-\end_inset
-
-
-\begin_inset Quotes cld
-\end_inset
+gtycon = qconid
+\end_layout
-]
-\begin_inset Quotes crd
\end_inset
\end_layout
-\end_inset
-
-
+\begin_layout Standard
+Un tipo puede ser un
+\family typewriter
+qconid
+\family default
+, cuyo significado depende del entorno, y esta definición puede aceptar
+ un número fijo de parámetros que también son tipos.
\end_layout
\begin_layout Standard
@@ -1206,17 +1285,173 @@ iguales
\end_layout
\begin_layout Standard
-\begin_inset Note Note
-status open
+Un
+\family typewriter
+varid
+\family default
+ representa una variable libre, y cuando el tipo que se asigna a una expresión
+ tiene alguna variable libre, el tipo de la expresión es
+\series bold
+polimórfico
+\series default
+, genérico sobre los valores de las variables libres.
+\end_layout
-\begin_layout Plain Layout
+\begin_layout Standard
+Tipos primitivos en el
+\family typewriter
+Prelude
+\family default
+:
+\end_layout
+
+\begin_layout Description
+
+\family typewriter
+Char
+\family default
+ Caracteres Unicode.
+\end_layout
+
+\begin_layout Description
+
+\family typewriter
+Double
+\family default
+ Números de punto flotante de precisión doble.
+\end_layout
+
+\begin_layout Description
+
+\family typewriter
+Float
+\family default
+ Números de punto flotante de precisión simple.
+\end_layout
+
+\begin_layout Description
+
+\family typewriter
+Int
+\begin_inset space ~
+\end_inset
+
+=
+\begin_inset space ~
+\end_inset
+
+minBound
+\begin_inset space ~
+\end_inset
+
+...
+\begin_inset space ~
+\end_inset
+
+-1
+\begin_inset space ~
+\end_inset
+
+|
+\begin_inset space ~
+\end_inset
+
+0
+\begin_inset space ~
+\end_inset
+
+|
+\begin_inset space ~
+\end_inset
+
+1
+\begin_inset space ~
+\end_inset
+
+...
+\begin_inset space ~
+\end_inset
+
+maxBound
+\family default
+ Enteros de tamaño limitado, con al menos los del rango
+\begin_inset Formula $[-2^{29},2^{29})$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Description
+
+\family typewriter
+Integer
+\begin_inset space ~
+\end_inset
+
+=
+\begin_inset space ~
+\end_inset
+
+...
+\begin_inset space ~
+\end_inset
+
+-1
+\begin_inset space ~
+\end_inset
+
+|
+\begin_inset space ~
+\end_inset
+
+0
+\begin_inset space ~
+\end_inset
+
+|
+\begin_inset space ~
+\end_inset
+
+1
+\begin_inset space ~
+\end_inset
+
+...
+
+\family default
+ Enteros de tamaño arbitrario.
+\end_layout
+
+\begin_layout Standard
+También son predefinidos las
+\series bold
+tuplas
+\series default
+, productos directos de un número fijo de tipos escritos entre paréntesis,
+ las
+\series bold
+listas
+\series default
+, secuencias finitas de elementos del mismo tipo escrito entre corchetes,
+ y el
+\series bold
+tipo unidad
+\series default
+
+\family typewriter
+()
+\family default
+, con un solo elemento:
+\end_layout
+
+\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
-aexp /=
+atype /=
\begin_inset Quotes cld
\end_inset
@@ -1224,7 +1459,7 @@ aexp /=
\begin_inset Quotes cld
\end_inset
- exp *(
+ type 1*(
\begin_inset Quotes cld
\end_inset
@@ -1232,7 +1467,7 @@ aexp /=
\begin_inset Quotes crd
\end_inset
- exp)
+ type
\begin_inset Quotes cld
\end_inset
@@ -1248,25 +1483,49 @@ aexp /=
\begin_inset Quotes cld
\end_inset
- exp *(
+ type
\begin_inset Quotes cld
\end_inset
-,
+]
\begin_inset Quotes crd
\end_inset
- exp)
+
+\end_layout
+
+\begin_layout Plain Layout
+
+gtycon /=
\begin_inset Quotes cld
\end_inset
-]
+(
+\begin_inset Quotes cld
+\end_inset
+
+
+\begin_inset Quotes cld
+\end_inset
+
+)
\begin_inset Quotes crd
\end_inset
+ /
+\begin_inset Quotes cld
+\end_inset
-\end_layout
+[
+\begin_inset Quotes cld
+\end_inset
+
+\begin_inset Quotes cld
+\end_inset
+
+]
+\begin_inset Quotes crd
\end_inset
@@ -1278,65 +1537,195 @@ aexp /=
\end_layout
\begin_layout Standard
-\begin_inset Note Note
+Podemos definir nuevos tipos para aumentar la seguridad de los programas:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
status open
\begin_layout Plain Layout
-(*), (<=), ->, (+), div, (^), (/), (.), Float, pi, Integer, not, True, False,
- (1*,), (), [*,], [], (:), otherwise, error, (-)
+
+topdecl /=
+\begin_inset Quotes cld
+\end_inset
+
+data
+\begin_inset Quotes crd
+\end_inset
+
+ [context
+\begin_inset Quotes cld
+\end_inset
+
+=>
+\begin_inset Quotes crd
+\end_inset
+
+] simpletype
+\begin_inset Quotes cld
+\end_inset
+
+=
+\begin_inset Quotes crd
+\end_inset
+
+ constrs [deriving]
\end_layout
+\begin_layout Plain Layout
+
+constrs = constr *(
+\begin_inset Quotes cld
\end_inset
+|
+\begin_inset Quotes crd
+\end_inset
+ constr)
\end_layout
-\begin_layout Standard
-\begin_inset Note Note
-status open
+\begin_layout Plain Layout
+
+constr = conid *atype / (btype /
+\begin_inset Quotes cld
+\end_inset
+
+!
+\begin_inset Quotes crd
+\end_inset
+
+ atype) conop (btype /
+\begin_inset Quotes cld
+\end_inset
+
+!
+\begin_inset Quotes crd
+\end_inset
+
+ atype)
+\end_layout
\begin_layout Plain Layout
+
+simpletype = conid *varid
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Cada
+\family typewriter
+constr
+\family default
+ se refiere al tipo producto de los
+\family typewriter
+atype
+\family default
+ etiquetado con el
+\family typewriter
+conid
+\family default
+, o bien a un tipo unipuntual con ese nombre, y el tipo
+\family typewriter
+simpletype
+\family default
+ es la unión disjunta de estos tipos producto y de
+\begin_inset Formula $\{\bot\}$
+\end_inset
+
+.
+ Si
+\family typewriter
+simpletype
+\family default
+ contiene variables, estas corresponden a parámetros de tipo, y los
+\family typewriter
+constrs
+\family default
+ solo pueden contener variables que aparezcan en el
+\family typewriter
+simpletype
+\family default
+.
+ El
+\family typewriter
+Prelude
+\family default
+ define
+\family typewriter
+data Bool = False | True
+\family default
+.
+\end_layout
+
+\begin_layout Standard
+También es posible añadir nombres a los campos:
+\end_layout
+
+\begin_layout Standard
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
-funlhs /=
+constr /= con
\begin_inset Quotes cld
\end_inset
-(
+{
\begin_inset Quotes cld
\end_inset
- funlhs
+ [fielddecl *(
\begin_inset Quotes cld
\end_inset
-)
+,
\begin_inset Quotes crd
\end_inset
- 1*apat
-\end_layout
+ fielddecl)]
+\begin_inset Quotes cld
+\end_inset
+
+}
+\begin_inset Quotes crd
+\end_inset
-\begin_layout Plain Layout
-lpat /= gcon 1*apat
\end_layout
\begin_layout Plain Layout
-guards /=
+fielddecl = vars
\begin_inset Quotes cld
\end_inset
-|
+::
\begin_inset Quotes crd
\end_inset
- guard *(
+ (type /
+\begin_inset Quotes cld
+\end_inset
+
+!
+\begin_inset Quotes crd
+\end_inset
+
+ atype)
+\end_layout
+
+\begin_layout Plain Layout
+
+vars = var *(
\begin_inset Quotes cld
\end_inset
@@ -1344,114 +1733,257 @@ guards /=
\begin_inset Quotes crd
\end_inset
- guard)
+ var)
\end_layout
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Cada
+\family typewriter
+var
+\family default
+ define un campo del tipo producto, y por cada una se crea una función del
+ tipo definido al tipo de la variable que devuelve el valor en esa posición
+ si la variable es de la variante
+\family typewriter
+con
+\family default
+ o
+\begin_inset Formula $\bot$
+\end_inset
+
+ en otro caso.
+ Un
+\series bold
+tipo recursivo
+\series default
+ es uno que se tiene al mismo en la parte derecha de la definición, consiguiendo
+ valores recursivos.
+\end_layout
+
+\begin_layout Standard
+Los
+\series bold
+sinónimos de tipo
+\series default
+ permiten definir abreviaturas para tipos comunes, que internamente se expanden
+ al tipo a la derecha:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
\begin_layout Plain Layout
-apat /=
+topdecl /=
\begin_inset Quotes cld
\end_inset
-(
+type
+\begin_inset Quotes crd
+\end_inset
+
+ simpletype
\begin_inset Quotes cld
\end_inset
- pat 1*(
+=
+\begin_inset Quotes crd
+\end_inset
+
+ type
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Las cadenas de caracteres se definen como
+\family typewriter
+type String = [Char]
+\family default
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+topdecl /=
\begin_inset Quotes cld
\end_inset
-,
+newtype
\begin_inset Quotes crd
\end_inset
- pat)
+ [context
\begin_inset Quotes cld
\end_inset
-)
+=>
\begin_inset Quotes crd
\end_inset
- /
+] simpletype = newconstr [deriving]
+\end_layout
+
+\begin_layout Plain Layout
+
+newconstr = con atype / con
\begin_inset Quotes cld
\end_inset
-[
+{
\begin_inset Quotes cld
\end_inset
- pat *(
+ var
\begin_inset Quotes cld
\end_inset
-,
+::
\begin_inset Quotes crd
\end_inset
- pat)
+ type
\begin_inset Quotes cld
\end_inset
-]
+}
\begin_inset Quotes crd
\end_inset
- / gcon
+
\end_layout
-\begin_layout Plain Layout
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Crea un tipo que etiqueta a otro.
+ Equivale a cambiar
+\family typewriter
+newtype
+\family default
+ por
+\family typewriter
+data
+\family default
+ pero sin añadir un
+\begin_inset Formula $\bot$
+\end_inset
-aexp /= gcon
+ adicional.
\end_layout
+\begin_layout Section
+Clases de tipos
+\end_layout
+
+\begin_layout Standard
+Son una forma de polimorfismo basada en clases cuyas instancias son tipos:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
\begin_layout Plain Layout
-gtycon /=
+topdecl /=
\begin_inset Quotes cld
\end_inset
-(
+class
+\begin_inset Quotes crd
+\end_inset
+
+ [scontext
\begin_inset Quotes cld
\end_inset
-
+=>
+\begin_inset Quotes crd
+\end_inset
+
+] conid varid [
\begin_inset Quotes cld
\end_inset
-->
+where
\begin_inset Quotes crd
\end_inset
-
+ cdecls]
+\end_layout
+
+\begin_layout Plain Layout
+
+ /
\begin_inset Quotes cld
\end_inset
-)
+instance
\begin_inset Quotes crd
\end_inset
- /
+ [scontext
\begin_inset Quotes cld
\end_inset
-(
+=>
+\begin_inset Quotes crd
+\end_inset
+
+] qconid inst [
\begin_inset Quotes cld
\end_inset
- 1*
+where
\begin_inset Quotes crd
\end_inset
-,
+ idecls]
+\end_layout
+
+\begin_layout Plain Layout
+
+cdecls =
+\begin_inset Quotes cld
+\end_inset
+
+{
+\begin_inset Quotes cld
+\end_inset
+
+ [cdecl *(
+\begin_inset Quotes cld
+\end_inset
+
+;
\begin_inset Quotes crd
\end_inset
-
+ cdecl)
\begin_inset Quotes cld
\end_inset
-)
+}
\begin_inset Quotes crd
\end_inset
@@ -1460,15 +1992,15 @@ gtycon /=
\begin_layout Plain Layout
-gcon =
+inst = gtycon /
\begin_inset Quotes cld
\end_inset
(
-\begin_inset Quotes crd
+\begin_inset Quotes cld
\end_inset
-
+ gtycon *varid
\begin_inset Quotes cld
\end_inset
@@ -1480,11 +2012,40 @@ gcon =
\begin_inset Quotes cld
\end_inset
+(
+\begin_inset Quotes cld
+\end_inset
+
+ varid 1*(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ varid)
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+ /
+\end_layout
+
+\begin_layout Plain Layout
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
[
\begin_inset Quotes cld
\end_inset
-
+ varid
\begin_inset Quotes cld
\end_inset
@@ -1500,15 +2061,15 @@ gcon =
\begin_inset Quotes cld
\end_inset
- 1*
-\begin_inset Quotes crd
+ varid
+\begin_inset Quotes cld
\end_inset
-,
+->
\begin_inset Quotes crd
\end_inset
-
+ varid
\begin_inset Quotes cld
\end_inset
@@ -1521,50 +2082,150 @@ gcon =
\begin_layout Plain Layout
-op = varop / conop
-\end_layout
+idecls =
+\begin_inset Quotes cld
+\end_inset
-\begin_layout Plain Layout
+{
+\begin_inset Quotes cld
+\end_inset
-conop =
+ [idecl *(
\begin_inset Quotes cld
\end_inset
-`
+;
\begin_inset Quotes crd
\end_inset
- conid
+ idecl)]
\begin_inset Quotes cld
\end_inset
-`
+}
\begin_inset Quotes crd
\end_inset
\end_layout
-\begin_layout Plain Layout
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Una declaración
+\family typewriter
+class
+\family default
+ define una clase
+\family typewriter
+conid
+\family default
+ y una serie de vínculos en el contexto global dados por las asignaciones
+ de tipo en las
+\family typewriter
+cdecl
+\family default
+, en las que
+\family typewriter
+varid
+\family default
+ se refiere a un tipo cualquiera de clase
+\family typewriter
+conid
+\family default
+ y debe aparecer alguna vez en el tipo.
+ Una
+\series bold
+declaración de instancia
+\series default
+
+\family typewriter
+instance
+\family default
+ indica que el tipo
+\family typewriter
+inst
+\family default
+ es de la clase
+\family typewriter
+qconid
+\family default
+ y da las definiciones de los vínculos establecidos por la clase cuando
+ el tipo
+\family typewriter
+varid
+\family default
+ se sustituye por
+\family typewriter
+inst
+\family default
+, llamadas
+\series bold
+métodos
+\series default
+.
+ Los nombres de métodos son miembros de una única clase, lo que evita conflictos
+ entre nombres.
+\end_layout
-qop = qvarop / qconop
+\begin_layout Standard
+La declaración
+\family typewriter
+class
+\family default
+ puede contener definiciones por defecto para los vínculos, en cuyo caso
+ no es necesario dar estas definiciones en las instancias, y también puede
+ declarar la aridad de operadores definidos en la clase.
+ Sin embargo, es común que las definiciones por defecto estén unas en función
+ de otras y haya que definir al menos un elemento para romper el ciclo.
+ La
+\series bold
+definición mínima completa
+\series default
+ de una clase es cualquier conjunto minimal de definiciones de la clase
+ que deben definir las instancias.
\end_layout
+\begin_layout Standard
+Las declaraciones pueden tener un
+\series bold
+contexto
+\series default
+ para restringir los valores por los que se pueden sustituir las variables
+ de tipo:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
\begin_layout Plain Layout
-qvarop = qvarsym /
+context = class /
\begin_inset Quotes cld
\end_inset
-`
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [class *(
+\begin_inset Quotes cld
+\end_inset
+
+,
\begin_inset Quotes crd
\end_inset
- qvarid
+ class)]
\begin_inset Quotes cld
\end_inset
-`
+)
\begin_inset Quotes crd
\end_inset
@@ -1573,19 +2234,19 @@ qvarop = qvarsym /
\begin_layout Plain Layout
-qconop = gconsym /
+class = qconid varid / qconid
\begin_inset Quotes cld
\end_inset
-`
-\begin_inset Quotes crd
+(
+\begin_inset Quotes cld
\end_inset
- qconid
+ varid 1*atype
\begin_inset Quotes cld
\end_inset
-`
+)
\begin_inset Quotes crd
\end_inset
@@ -1594,17 +2255,178 @@ qconop = gconsym /
\begin_layout Plain Layout
-gconsym =
+scontext = simpleclass /
\begin_inset Quotes cld
\end_inset
-:
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [simpleclass *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ simpleclass)]
+\begin_inset Quotes cld
+\end_inset
+
+)
\begin_inset Quotes crd
\end_inset
- / qconsym
+
+\end_layout
+
+\begin_layout Plain Layout
+
+simpleclass = qconid varid
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Las sustituciones deben respetar que cada
+\family typewriter
+varid
+\family default
+ o
+\family typewriter
+varid 1*atype
+\family default
+ sea de la clase
+\family typewriter
+qconid
+\family default
+.
+ Esto es necesario cuando en la definición de una función se quieren usar
+ funciones definidas en una clase, y de hecho el tipo de estas funciones
+ tiene una restricción en su contexto.
+\end_layout
+
+\begin_layout Standard
+Si una clase
+\family typewriter
+class
+\family default
+...
+
+\family typewriter
+ =>
+\emph on
+Foo a
+\family default
+\emph default
+ tiene
+\family typewriter
+\emph on
+Bar a
+\family default
+\emph default
+ en su contexto,
+\family typewriter
+\emph on
+Bar
+\family default
+\emph default
+ es
+\series bold
+superclase
+\series default
+ de
+\family typewriter
+\emph on
+Foo
+\family default
+\emph default
+ y
+\family typewriter
+\emph on
+Foo
+\family default
+\emph default
+ es
+\series bold
+subclase
+\series default
+ de
+\family typewriter
+\emph on
+Bar
+\family default
+\emph default
+, y todo contexto que indique que una variable o expresión tiene tipo
+\family typewriter
+\emph on
+Foo
+\family default
+\emph default
+ permite usar sobre ella además de las operaciones de
+\family typewriter
+\emph on
+Foo
+\family default
+\emph default
+ las de
+\family typewriter
+\emph on
+Bar
+\family default
+\emph default
+, recursivamente.
+ El contexto de un método no puede tener restricciones sobre la variable
+ de la clase.
+\end_layout
+
+\begin_layout Standard
+Se pueden derivar automáticamente las definiciones de algunas clases predefinida
+s:
\end_layout
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+deriving =
+\begin_inset Quotes cld
+\end_inset
+
+deriving
+\begin_inset Quotes crd
+\end_inset
+
+ (qconid /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [qconid *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ qconid)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
\end_inset
@@ -1615,11 +2437,69 @@ gconsym =
\end_layout
+\begin_layout Standard
+Haskell soporta
+\series bold
+tipos de alto rango
+\series default
+, lo que significa que las instancias de una clase pueden ser tipos que
+ acepten parámetros, y no necesariamente tipos completos.
+\end_layout
+
\begin_layout Section
Expresiones
\end_layout
\begin_layout Standard
+Haskell tiene
+\series bold
+disciplina de tipos
+\series default
+, consistente en que toda expresión bien formada tiene un tipo deducible
+ a partir de sus subexpresiones y el contexto, y las expresiones a las que
+ no se puede asignar un tipo están mal formadas.
+ Esto permite detectar errores antes de la evaluación y fuerza al programador
+ se plantearse tipos apropiados para los valores, ayudando a diseñar programas
+ claros y bien estructurados.
+\end_layout
+
+\begin_layout Standard
+Al empezar a evaluar una expresión, primero se comprueba que la sintaxis
+ sea correcta y, si no lo es, se produce un
+\series bold
+error de sintaxis
+\series default
+, y luego se comprueba si tiene un tipo correcto y si no se produce un
+\series bold
+error de tipo
+\series default
+.
+\end_layout
+
+\begin_layout Standard
+La
+\series bold
+evaluación ansiosa
+\series default
+ o
+\series bold
+llamada por valor
+\series default
+ es como el orden aplicativo pero sin evaluar en el interior de abstracciones,
+ y la
+\series bold
+evaluación perezosa
+\series default
+ o
+\series bold
+llamada por nombre
+\series default
+ es como el orden normal pero sin evaluar en el interior de abstracciones.
+ Haskell usa evaluación perezosa, que al contrario que la ansiosa garantiza
+ la terminación si la expresión es normalizable.
+\end_layout
+
+\begin_layout Standard
\begin_inset listings
inline false
status open
@@ -1678,7 +2558,23 @@ in
\begin_layout Plain Layout
-aexp = qvar / literal
+aexp = qvar / literal /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ exp
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
\end_layout
\begin_layout Plain Layout
@@ -1765,8 +2661,21 @@ lexp qop infixexp
\family typewriter
(qop) lexp infixexp
\family default
-, aunque realmente distintos operadores tienen distinta precedencia y asociativi
-dad, establecidas con la sintaxis:
+, aunque realmente distintos operadores tienen distinta precedencia del
+ 0 al 9 y asociatividad.
+ El operador
+\family typewriter
+-
+\family default
+ es el único unario, y representa la negación.
+\end_layout
+
+\begin_layout Standard
+Una
+\series bold
+sección
+\series default
+ es un operador con una expresión delante o detrás:
\end_layout
\begin_layout Standard
@@ -1776,29 +2685,19 @@ status open
\begin_layout Plain Layout
-gendecl /= fixity [integer] ops
-\end_layout
-
-\begin_layout Plain Layout
-
-ops = op *(
+aexp /=
\begin_inset Quotes cld
\end_inset
-,
-\begin_inset Quotes crd
+(
+\begin_inset Quotes cld
\end_inset
- op)
-\end_layout
-
-\begin_layout Plain Layout
-
-fixity =
+ infixexp qop
\begin_inset Quotes cld
\end_inset
-infixl
+)
\begin_inset Quotes crd
\end_inset
@@ -1806,15 +2705,23 @@ infixl
\begin_inset Quotes cld
\end_inset
-infixr
+(
+\begin_inset Quotes cld
+\end_inset
+
+ !
\begin_inset Quotes crd
\end_inset
- /
+-
+\begin_inset Quotes crd
+\end_inset
+
+ qop infixexp
\begin_inset Quotes cld
\end_inset
-infix
+)
\begin_inset Quotes crd
\end_inset
@@ -1827,29 +2734,106 @@ infix
\end_layout
\begin_layout Standard
-El entero opcional va del 0 al 9 y es mayor a mayor precedencia, y se usa
-
+
\family typewriter
-infixl
+(
+\emph on
+infixexp qop
+\emph default
+)
\family default
- para indicar asociatividad por la izquierda o
+ equivale a
\family typewriter
-infixr
+
+\backslash
+y ->
+\emph on
+infixexp qop
+\emph default
+ y
\family default
- por la derecha.
- El operador
+ y
\family typewriter
--
+(
+\emph on
+qop infixexp
+\emph default
+)
\family default
- es el único unario, y representa la negación.
+ a
+\family typewriter
+
+\backslash
+x -> x
+\emph on
+qop infixexp
+\family default
+\emph default
+.
\end_layout
\begin_layout Standard
-Una
-\series bold
-sección
-\series default
- es un operador con una expresión delante o detrás:
+La negación
+\family typewriter
+-
+\emph on
+a
+\family default
+\emph default
+ equivale a
+\family typewriter
+Prelude.negate
+\emph on
+a
+\family default
+\emph default
+; los literales
+\family typewriter
+char
+\family default
+ son de tipo
+\family typewriter
+Char
+\family default
+; los
+\family typewriter
+string
+\family default
+ de tipo
+\family typewriter
+String
+\family default
+; los
+\family typewriter
+integer
+\family default
+ equivalen a
+\family typewriter
+Prelude.fromInteger (
+\emph on
+x
+\emph default
+ :: Prelude.Integer)
+\family default
+, siendo
+\family typewriter
+\emph on
+x
+\family default
+\emph default
+ el entero indicado, y los
+\family typewriter
+float
+\family default
+ a
+\family typewriter
+Prelude.fromRational (
+\emph on
+x
+\emph default
+ :: Data.Ratio.Rational)
+\family default
+.
\end_layout
\begin_layout Standard
@@ -1867,7 +2851,15 @@ aexp /=
\begin_inset Quotes cld
\end_inset
- infixexp qop
+ exp 1*(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ exp)
\begin_inset Quotes cld
\end_inset
@@ -1879,11 +2871,40 @@ aexp /=
\begin_inset Quotes cld
\end_inset
+[
+\begin_inset Quotes cld
+\end_inset
+
+ exp *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ exp)
+\begin_inset Quotes cld
+\end_inset
+
+]
+\begin_inset Quotes crd
+\end_inset
+
+ / gcon
+\end_layout
+
+\begin_layout Plain Layout
+
+gcon =
+\begin_inset Quotes cld
+\end_inset
+
(
\begin_inset Quotes cld
\end_inset
- qop infixexp
+
\begin_inset Quotes cld
\end_inset
@@ -1891,50 +2912,96 @@ aexp /=
\begin_inset Quotes crd
\end_inset
+ /
+\begin_inset Quotes cld
+\end_inset
+
+[
+\begin_inset Quotes cld
+\end_inset
+
+\begin_inset Quotes cld
+\end_inset
+
+]
+\begin_inset Quotes crd
+\end_inset
+
+ / qcon
\end_layout
+\begin_layout Plain Layout
+
+gconsym /=
+\begin_inset Quotes cld
+\end_inset
+
+:
+\begin_inset Quotes crd
\end_inset
\end_layout
-\begin_layout Standard
+\end_inset
+
+\end_layout
+
+\begin_layout Standard
+La primera sintaxis indica una tupla, la segunda una lista de un tamaño
+ dado,
\family typewriter
-(
+()
+\family default
+ el tipo unidad,
+\family typewriter
+[]
+\family default
+ la lista vacía y un
+\family typewriter
+qconid
+\family default
+ es un constructor de tipo, que actúa como una función currificada que recibe
+ tantos parámetros como aparezcan en la definición y del tipo correcto y
+ devuelve un elemento del tipo definido.
+ Finalmente,
+\family typewriter
+(:) :: a -> [a] -> [a]
+\family default
+ es un operador asociativo por la derecha con precedencia 5 que añade un
+ elemento al inicio de una lista, con lo que
+\family typewriter
+[
\emph on
-infixexp qop
+a1
\emph default
-)
+,
\family default
- equivale a
+...
\family typewriter
-
-\backslash
-y ->
+,
\emph on
-infixexp qop
+an
\emph default
- y
+]
\family default
- y
+ equivale a
\family typewriter
-(
\emph on
-qop infixexp
+a1
\emph default
-)
+:
\family default
- a
+...
\family typewriter
-
-\backslash
-x -> x
+:
\emph on
-qop infixexp
-\family default
+an
\emph default
+:[]
+\family default
.
\end_layout
@@ -1949,7 +3016,7 @@ status open
\begin_layout Plain Layout
-pat = lpat
+pat = lpat / lpat qconop pat
\end_layout
\begin_layout Plain Layout
@@ -1962,7 +3029,7 @@ lpat = apat /
\begin_inset Quotes crd
\end_inset
- (integer / float)
+ (integer / float) / gcon 1*apat
\end_layout
\begin_layout Plain Layout
@@ -1999,7 +3066,102 @@ _
\begin_inset Quotes crd
\end_inset
+ / gcon /
+\end_layout
+
+\begin_layout Plain Layout
+
+ / qcon
+\begin_inset Quotes cld
+\end_inset
+
+{
+\begin_inset Quotes cld
+\end_inset
+
+ [fpat *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ fpat)]
+\begin_inset Quotes cld
+\end_inset
+
+}
+\begin_inset Quotes crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ pat 1*(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ pat)
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+ /
+\end_layout
+
+\begin_layout Plain Layout
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+[
+\begin_inset Quotes cld
+\end_inset
+
+ pat *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ pat)
+\begin_inset Quotes cld
+\end_inset
+
+]
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+fpat = qvar
+\begin_inset Quotes cld
+\end_inset
+
+=
+\begin_inset Quotes crd
+\end_inset
+ pat
\end_layout
\end_inset
@@ -2049,8 +3211,68 @@ apat
.
Una misma variable no puede aparecer dos veces en la misma lista de patrones,
ni siquiera como subpatrón.
- Un literal o su negación no crea vínculos y encaja sólo si el argumento
- es igual a él.
+ Un literal, su negación o un
+\family typewriter
+gcon
+\family default
+ suelto recibe un argumento del tipo que tendría como expresión, no crea
+ vínculos y encaja sólo si el argumento es igual a él.
+
+\end_layout
+
+\begin_layout Standard
+Un patrón
+\family typewriter
+qcon 1*apat
+\family default
+, con tantos
+\family typewriter
+apat
+\family default
+ como parámetros tenga el constructor
+\family typewriter
+qcon
+\family default
+, acepta un argumento del tipo que crearía el constructor y encaja si este
+ es de la variante dada y cada
+\family typewriter
+apat
+\family default
+ encaja con el elemento correspondiente de la variante, añadiendo los vínculos
+ de los
+\family typewriter
+apat
+\family default
+.
+ Uno
+\family typewriter
+qcon {
+\family default
+...
+
+\family typewriter
+ }
+\family default
+ es similar pero para constructores definidos con llaves, y
+\family typewriter
+(
+\family default
+...
+
+\family typewriter
+ )
+\family default
+ y
+\family typewriter
+[
+\family default
+...
+
+\family typewriter
+ ]
+\family default
+ hacen lo propio con tuplas y listas, entendiendo que las listas deben tener
+ tantos elementos como patrones haya para encajar.
\end_layout
\begin_layout Standard
@@ -2354,6 +3576,28 @@ exp
\family default
\emph default
.
+ Todas las guardas deben tener tipo
+\family typewriter
+Bool
+\family default
+ y todas las partes derechas de
+\family typewriter
+gdpat
+\family default
+ o
+\family typewriter
+alt
+\family default
+ de la misma
+\family typewriter
+case
+\family default
+ deben tener el mismo tipo o intersección no vacía, y el tipo de la expresión
+
+\family typewriter
+case
+\family default
+ será la intersección de los tipos de las partes derechas.
\end_layout
\begin_layout Standard
@@ -2464,6 +3708,81 @@ exp
\end_inset
en otro caso.
+ El tipo de los parámetros puede ser restringido por los patrones y los
+ usos que se les da a las variables en
+\family typewriter
+\emph on
+exp
+\family default
+\emph default
+, y el tipo de la función es de la forma [
+\family typewriter
+\emph on
+contexto
+\emph default
+ =>
+\family default
+]
+\family typewriter
+
+\emph on
+t
+\begin_inset Formula $_{1}$
+\end_inset
+
+ ->
+\family default
+\emph default
+...
+
+\family typewriter
+\emph on
+ -> t
+\begin_inset Formula $_{n}$
+\end_inset
+
+
+\emph default
+ ->
+\emph on
+r
+\family default
+\emph default
+, donde los
+\family typewriter
+\emph on
+t
+\begin_inset Formula $_{i}$
+\end_inset
+
+
+\family default
+\emph default
+ son los tipos de los parámetros, que pueden contener variables posiblemente
+ restringidas por el
+\family typewriter
+\emph on
+contexto
+\family default
+\emph default
+, y
+\family typewriter
+\emph on
+r
+\family default
+\emph default
+ es el tipo que tiene el resultado cuando las variables tienen los tipos
+ dados por los
+\family typewriter
+\emph on
+t
+\begin_inset Formula $_{i}$
+\end_inset
+
+
+\family default
+\emph default
+.
\end_layout
\begin_layout Section
@@ -2482,6 +3801,10 @@ definición
asignación de tipo
\series default
opcional, que indica el tipo de la variable, y una serie de ecuaciones.
+ La asignación del tipo debe corresponder o al tipo inferido o a una restricción
+, no se puede dar más de una asignación a la misma variable y, si se asigna
+ un tipo más restringido, no se puede usar la variable como si tuviera el
+ tipo más general.
\end_layout
\begin_layout Standard
@@ -2496,6 +3819,16 @@ decl = gendecl / (funlhs / pat) rhs
\begin_layout Plain Layout
+cdecl = gendecl / (funlhs / var) rhs
+\end_layout
+
+\begin_layout Plain Layout
+
+idecl = (funlhs / var) rhs /
+\end_layout
+
+\begin_layout Plain Layout
+
gendecl = vars
\begin_inset Quotes cld
\end_inset
@@ -2504,12 +3837,12 @@ gendecl = vars
\begin_inset Quotes crd
\end_inset
- type
+ type / fixity [integer] ops
\end_layout
\begin_layout Plain Layout
-vars = var *(
+ops = op *(
\begin_inset Quotes cld
\end_inset
@@ -2517,11 +3850,36 @@ vars = var *(
\begin_inset Quotes crd
\end_inset
- var)
+ op)
\end_layout
\begin_layout Plain Layout
+fixity =
+\begin_inset Quotes cld
+\end_inset
+
+infixl
+\begin_inset Quotes crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+infixr
+\begin_inset Quotes crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+infix
+\begin_inset Quotes crd
+\end_inset
+
+
\end_layout
\end_inset
@@ -2682,6 +4040,12 @@ exp
\family default
\emph default
.
+ La inferencia de tipos funciona como si la función se hubiera definido
+ mediante una abstracción con dentro un
+\family typewriter
+case
+\family default
+.
\end_layout
\begin_layout Standard
@@ -2702,5 +4066,26 @@ pat
es una variable.
\end_layout
+\begin_layout Standard
+El segundo tipo de
+\family typewriter
+gendecl
+\family default
+ establece que los operadores indicados tengan precedencia dada por el entero
+ opcional y asociatividad por la izquierda (
+\family typewriter
+infixl
+\family default
+), por la derecha (
+\family typewriter
+infixr
+\family default
+) o ninguna (
+\family typewriter
+infix
+\family default
+).
+\end_layout
+
\end_body
\end_document
diff --git a/pia/n5.lyx b/pia/n5.lyx
new file mode 100644
index 0000000..40309cd
--- /dev/null
+++ b/pia/n5.lyx
@@ -0,0 +1,1876 @@
+#LyX 2.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 544
+\begin_document
+\begin_header
+\save_transient_properties true
+\origin unavailable
+\textclass book
+\begin_preamble
+\input{../defs}
+\end_preamble
+\use_default_options true
+\maintain_unincluded_children false
+\language spanish
+\language_package default
+\inputencoding auto
+\fontencoding global
+\font_roman "default" "default"
+\font_sans "default" "default"
+\font_typewriter "default" "default"
+\font_math "auto" "auto"
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_osf false
+\font_sf_scale 100 100
+\font_tt_scale 100 100
+\use_microtype false
+\use_dash_ligatures true
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 1
+\use_package amssymb 1
+\use_package cancel 1
+\use_package esint 1
+\use_package mathdots 1
+\use_package mathtools 1
+\use_package mhchem 1
+\use_package stackrel 1
+\use_package stmaryrd 1
+\use_package undertilde 1
+\cite_engine basic
+\cite_engine_type default
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 1
+\use_minted 0
+\index Index
+\shortcut idx
+\color #008000
+\end_index
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\is_math_indent 0
+\math_numbering_side default
+\quotes_style french
+\dynamic_quotes 0
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tracking_changes false
+\output_changes false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\end_header
+
+\begin_body
+
+\begin_layout Standard
+Haskell tiene un preludio estándar con tipos y funciones predefinidos.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+infixr 9 .
+\end_layout
+
+\begin_layout Plain Layout
+
+infixr 8 ^
+\end_layout
+
+\begin_layout Plain Layout
+
+infixl 7 *, /, `quot`, `rem`, `div`, `mod`
+\end_layout
+
+\begin_layout Plain Layout
+
+infixl 6 +, -
+\end_layout
+
+\begin_layout Plain Layout
+
+infix 4 ==, /=, <, <=, >=, >
+\end_layout
+
+\begin_layout Plain Layout
+
+infixr 3 &&
+\end_layout
+
+\begin_layout Plain Layout
+
+infixr 2 ||
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+^^, .., =<<, $, $!, `seq`
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Cuando se indica
+\family typewriter
+...
+
+\family default
+ en código significa que no se puede definir en Haskell.
+ Si se define que un tipo es de una clase, también lo es de sus superclases,
+ y si no se da la definición de la instancia de superclase es porque no
+ se puede definir en Haskell.
+\end_layout
+
+\begin_layout Section
+Clases derivables
+\end_layout
+
+\begin_layout Standard
+Estas clases se pueden derivar en una instancia
+\family typewriter
+data
+\family default
+ con al menos un constructor o una
+\family typewriter
+newtype
+\family default
+ si todos los tipos en los parámetros de todos los constructores son instancias
+ de la clase en algún contexto y no hay una declaración de instancia que
+ haga conflicto.
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+()
+\family default
+,
+\family typewriter
+(a,b)
+\family default
+ y
+\family typewriter
+(a,b,c)
+\family default
+ implementan
+\family typewriter
+Eq
+\family default
+,
+\family typewriter
+Ord
+\family default
+ y
+\family typewriter
+Bounded
+\family default
+ como se indica, y
+\family typewriter
+()
+\family default
+ también implementa
+\family typewriter
+Enum
+\family default
+.
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Eq
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+class Eq a where {-# MINIMAL (==) | (/=) #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ (==), (/=) :: a -> a -> Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+ x /= y = not (x == y)
+\end_layout
+
+\begin_layout Plain Layout
+
+ x == y = not (x /= y)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+\emph on
+a
+\emph default
+ ==
+\emph on
+b
+\family default
+\emph default
+ si
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ y
+\family typewriter
+\emph on
+b
+\family default
+\emph default
+ tienen el mismo constructor y todos sus campos son iguales (
+\family typewriter
+==
+\family default
+), salvo que si un campo de
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ o
+\family typewriter
+\emph on
+b
+\family default
+\emph default
+ es
+\begin_inset Formula $\bot$
+\end_inset
+
+,
+\family typewriter
+\emph on
+a
+\emph default
+ ==
+\emph on
+b
+\family default
+\emph default
+ devuelve
+\begin_inset Formula $\bot$
+\end_inset
+
+ si todos los campos anteriores al primer
+\begin_inset Formula $\bot$
+\end_inset
+
+ son iguales, y si
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ o
+\family typewriter
+\emph on
+b
+\family default
+\emph default
+ es
+\begin_inset Formula $\bot$
+\end_inset
+
+ el resultado es
+\begin_inset Formula $\bot$
+\end_inset
+
+.
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Ord
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+data Ordering = LT | EQ | GT
+\end_layout
+
+\begin_layout Plain Layout
+
+ deriving (Eq, Ord, Enum, Read, Show, Bounded)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class (Eq a) => Ord a where {-# MINIMAL compare | (<=) #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ compare :: a -> a -> Ordering
+\end_layout
+
+\begin_layout Plain Layout
+
+ (<), (<=), (>=), (>) :: a -> a -> Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+ max, min :: a -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ compare x y
+\end_layout
+
+\begin_layout Plain Layout
+
+ | x == y = EQ
+\end_layout
+
+\begin_layout Plain Layout
+
+ | x <= y = LT
+\end_layout
+
+\begin_layout Plain Layout
+
+ | True = GT
+\end_layout
+
+\begin_layout Plain Layout
+
+ x <= y = compare x y /= GT
+\end_layout
+
+\begin_layout Plain Layout
+
+ x < y = compare x y == LT
+\end_layout
+
+\begin_layout Plain Layout
+
+ x >= y = compare x y /= LT
+\end_layout
+
+\begin_layout Plain Layout
+
+ x > y = compare x y == GT
+\end_layout
+
+\begin_layout Plain Layout
+
+ max x y = if x <= y then y else x
+\end_layout
+
+\begin_layout Plain Layout
+
+ min x y = if x <= y then x else y
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+\emph on
+a
+\emph default
+ <=
+\emph on
+b
+\family default
+\emph default
+ si
+\family typewriter
+\emph on
+a
+\emph default
+==
+\emph on
+b
+\family default
+\emph default
+,
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ tiene un constructor definido más a la izquierda que el de
+\family typewriter
+\emph on
+b
+\family default
+\emph default
+ o ambos tienen el mismo y existe un campo cuyo valor en
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ es menor (
+\family typewriter
+<
+\family default
+) que en
+\family typewriter
+\emph on
+b
+\family default
+\emph default
+ y todos los anteriores son iguales, salvo que
+\family typewriter
+(<=)
+\family default
+ devuelve
+\begin_inset Formula $\bot$
+\end_inset
+
+ en los mismos casos que
+\family typewriter
+(==)
+\family default
+.
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Bounded
+\end_layout
+
+\begin_layout Standard
+Sólo si ningún constructor tiene campos o solo hay un constructor.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+class Bounded a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ minBound :: a
+\end_layout
+
+\begin_layout Plain Layout
+
+ maxBound :: a
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+En un enumerado,
+\family typewriter
+minBound
+\family default
+ es el elemento del primer constructor y
+\family typewriter
+maxBound
+\family default
+ el del último, y en otro caso
+\family typewriter
+minBound
+\family default
+ y
+\family typewriter
+maxBound
+\family default
+ son los elementos del único constructor con el
+\family typewriter
+minBound
+\family default
+ o el
+\family typewriter
+maxBound
+\family default
+ de cada campo.
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Enum
+\end_layout
+
+\begin_layout Standard
+Sólo si ningún constructor tiene campos.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+class Enum a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ toEnum :: Int -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ fromEnum :: a -> Int
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+toEnum 0
+\family default
+ devuelve el primer elemento del enumerado (el del primer constructor),
+
+\family typewriter
+toEnum 1
+\family default
+ el segundo, etc., y
+\family typewriter
+toEnum
+\emph on
+a
+\family default
+\emph default
+ devuelve
+\begin_inset Formula $\bot$
+\end_inset
+
+ para una entrada no definida.
+
+\family typewriter
+fromEnum
+\family default
+ es la inversa de
+\family typewriter
+toEnum
+\family default
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+succ, pred, enumFrom, enumThen, enumFromTo, enumFromThenTo
+\end_layout
+
+\end_inset
+
+
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+enumFrom y enumFromThen se definen de forma especial.
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Show
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+type ShowS = String -> String
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class Show a where {-# MINIMAL showsPrec | show #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ showsPrec :: Int -> a -> ShowS
+\end_layout
+
+\begin_layout Plain Layout
+
+ show :: a -> String
+\end_layout
+
+\begin_layout Plain Layout
+
+ showsPrec _ x s = show x ++ s
+\end_layout
+
+\begin_layout Plain Layout
+
+ show x = showsPrec 0 x
+\begin_inset Quotes cld
+\end_inset
+
+
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+showsPrec
+\emph on
+d x r
+\family default
+\emph default
+ devuelve una representación de
+\family typewriter
+\emph on
+x
+\family default
+\emph default
+ como expresión Haskell, entre paréntesis si el constructor de
+\family typewriter
+\emph on
+x
+\family default
+\emph default
+ tiene precedencia menor que
+\family typewriter
+\emph on
+d
+\family default
+\emph default
+ considerando que la precedencia de una aplicación funcional es 10, seguida
+ de
+\family typewriter
+\emph on
+r
+\family default
+\emph default
+.
+
+\end_layout
+
+\begin_layout Standard
+La representación está formada por el nombre del constructor y las representacio
+nes de los parámetros según su
+\family typewriter
+showsPrec
+\family default
+, posiblemente separados por espacios, y añadiendo paréntesis si hacen falta
+ por precedencia aunque no hagan falta por asociatividad.
+ El constructor se muestra en forma infija si y sólo si es un
+\family typewriter
+qconop
+\family default
+, y si usa sintaxis con llaves, la representación también, con los campos
+ en el mismo orden.
+ Puede haber más espaciado o paréntesis de lo necesario.
+\end_layout
+
+\begin_layout Subsection
+
+\family typewriter
+Read
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+type ReadS a = String -> [(a, String)]
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class Read a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ readsPrec :: Int -> ReadS a
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+readsPrec
+\emph on
+d s
+\family default
+\emph default
+ intenta leer del principio de
+\family typewriter
+\emph on
+s
+\family default
+\emph default
+ un elemento de tipo
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+ devuelto por
+\family typewriter
+showsPrec
+\family default
+ y devuelve una lista de pares con el valor leído y el resto de la cadena,
+ que será vacía si la entrada no es correcta.
+
+\family typewriter
+(
+\emph on
+x
+\emph default
+,
+\begin_inset Quotes qrd
+\end_inset
+
+
+\begin_inset Quotes qrd
+\end_inset
+
+)
+\family default
+ debe ser un elemento de
+\family typewriter
+readsPrec
+\emph on
+d
+\emph default
+ (showsPrec
+\emph on
+d x
+\emph default
+
+\begin_inset Quotes qld
+\end_inset
+
+
+\begin_inset Quotes qrd
+\end_inset
+
+)
+\family default
+.
+\end_layout
+
+\begin_layout Section
+Booleanos
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+data Bool = False | True deriving (Eq, Ord, Enum, Read, Show, Bounded)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+(&&), (||) :: Bool -> Bool -> Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+True && x = x
+\end_layout
+
+\begin_layout Plain Layout
+
+False && _ = False
+\end_layout
+
+\begin_layout Plain Layout
+
+True || _ = True
+\end_layout
+
+\begin_layout Plain Layout
+
+False || x = x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+not :: Bool -> Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+not True = False
+\end_layout
+
+\begin_layout Plain Layout
+
+not False = True
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+otherwise :: Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+otherwise = True
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Funciones
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+seq, ($), ($!)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+lstparams "language=Haskell"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+id :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+id x = x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+const :: a -> b -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+const x _ = x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+(.) :: (b -> c) -> (a -> b) -> a -> c
+\end_layout
+
+\begin_layout Plain Layout
+
+f .
+ g =
+\backslash
+x -> f (g x)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+flip :: (a -> b -> c) -> b -> a -> c
+\end_layout
+
+\begin_layout Plain Layout
+
+flip f x y = f y x
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+until
+\emph on
+f p
+\family default
+\emph default
+ evalúa
+\family typewriter
+\emph on
+f
+\family default
+\emph default
+ sobre un argumento hasta que cumple
+\family typewriter
+\emph on
+p
+\family default
+\emph default
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+until :: (a -> Bool) -> (a -> a) -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+until p f x -- until p f aplica f hasta que se cumple p
+\end_layout
+
+\begin_layout Plain Layout
+
+ | p x = x
+\end_layout
+
+\begin_layout Plain Layout
+
+ | otherwise = until p f (f x)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+error
+\emph on
+s
+\family default
+\emph default
+ devuelve
+\begin_inset Formula $\bot$
+\end_inset
+
+.
+ y, cuando se evalúa, imprime el error
+\family typewriter
+\emph on
+s
+\family default
+\emph default
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+error :: String -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+error s = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+undefined :: a
+\end_layout
+
+\begin_layout Plain Layout
+
+undefined = error
+\begin_inset Quotes cld
+\end_inset
+
+Prelude.undefined
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Tuplas
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+fst :: (a, b) -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+fst (x, y) = x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+snd :: (a, b) -> b
+\end_layout
+
+\begin_layout Plain Layout
+
+snd (x, y) = y
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+curry :: ((a, b) -> c) -> a -> b -> c
+\end_layout
+
+\begin_layout Plain Layout
+
+curry f x y = f (x, y)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+uncurry :: (a -> b -> c) -> (a, b) -> c
+\end_layout
+
+\begin_layout Plain Layout
+
+uncurry f (x, y) = f x y
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Clases numéricas
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+recip, (**), logBase, round, ceiling, floor, RealFloat
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+class (Eq a, Show a) => Num a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ (+), (-), (*) :: a -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ negate :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ abs, signum :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ fromInteger :: Integer -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ x - y = x + negate y
+\end_layout
+
+\begin_layout Plain Layout
+
+ negate x = 0 - x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class (Num a, Ord a) => Real a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ toRational :: a -> Rational
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class (Real a, Enum a) => Integral a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ {-# MINIMAL quotRem, toInteger #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ quot, rem, div, mod :: a -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ quotRem, divMod :: a -> a -> (a,a)
+\end_layout
+
+\begin_layout Plain Layout
+
+ toInteger :: a -> Integer
+\end_layout
+
+\begin_layout Plain Layout
+
+ divMod n d = if signum r == - signum d
+\end_layout
+
+\begin_layout Plain Layout
+
+ then (q-1, r+d)
+\end_layout
+
+\begin_layout Plain Layout
+
+ else (q, r)
+\end_layout
+
+\begin_layout Plain Layout
+
+ where (q, r) = quotRem n d
+\end_layout
+
+\begin_layout Plain Layout
+
+ n `quot` d = q where (q, r) = quotRem n d
+\end_layout
+
+\begin_layout Plain Layout
+
+ n `rem` d = r where (q, r) = quotRem n d
+\end_layout
+
+\begin_layout Plain Layout
+
+ n `div` d = q where (q, r) = divMod n d
+\end_layout
+
+\begin_layout Plain Layout
+
+ n `mod` d = r where (q, r) = divMod n d
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class (Num a) => Fractional a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ (/) :: a -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ fromRational :: Rational -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class (Fractional a) => Floating a where
+\end_layout
+
+\begin_layout Plain Layout
+
+ {#- MINIMAL pi, exp, log, sin, cos, asin, acos, atan, sinh, cosh,
+\end_layout
+
+\begin_layout Plain Layout
+
+ asinh, acosh, atanh #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ pi :: a
+\end_layout
+
+\begin_layout Plain Layout
+
+ exp, log, sqrt :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ sin, cos, tan, asin, acos, atan :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+ sinh, cosh, tanh, asinh, acosh, atanh :: a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ sqrt x = x ** 0.5
+\end_layout
+
+\begin_layout Plain Layout
+
+ tan x = sin x / cos x
+\end_layout
+
+\begin_layout Plain Layout
+
+ tanh x = sinh x / cosh x
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class RealFrac a where {-# MINIMAL properFraction #-}
+\end_layout
+
+\begin_layout Plain Layout
+
+ properFraction :: (Integral b) => a -> (b, a)
+\end_layout
+
+\begin_layout Plain Layout
+
+ truncate :: (Integral b) => a -> b
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ truncate = fst .
+ properFraction
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Funciones numéricas
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+subtract, (^^), realToFrac
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+even, odd :: (Integral a) => a -> Bool
+\end_layout
+
+\begin_layout Plain Layout
+
+even n = n `rem` 2 == 0
+\end_layout
+
+\begin_layout Plain Layout
+
+odd = not .
+ even
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+gcd, lcm :: (Integral a) => a -> a -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+gcd 0 0 = undefined
+\end_layout
+
+\begin_layout Plain Layout
+
+gcd x y = gcd' (abs x) (abs y)
+\end_layout
+
+\begin_layout Plain Layout
+
+ where gcd' x 0 = x
+\end_layout
+
+\begin_layout Plain Layout
+
+ gcd' x y = gcd' y (x `rem` y)
+\end_layout
+
+\begin_layout Plain Layout
+
+lcm _ 0 = 0
+\end_layout
+
+\begin_layout Plain Layout
+
+lcm 0 _ = 0
+\end_layout
+
+\begin_layout Plain Layout
+
+lcm x y = abs ((x `quot` (gcd x y)) * y)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+(^) :: (Num a, Integral b) => a -> b -> a
+\end_layout
+
+\begin_layout Plain Layout
+
+x ^ 0 = 1
+\end_layout
+
+\begin_layout Plain Layout
+
+x ^ (n+1) = x * x^n
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+fromIntegral :: (Integral a, Num b) => a -> b
+\end_layout
+
+\begin_layout Plain Layout
+
+fromIntegral = fromInteger .
+ toInteger
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Tipos numéricos
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+instance Bounded Int where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Integral Int where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Integral Integer where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance RealFrac Float where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Floating Float where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance RealFrac Double where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Floating Double where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Enum Float where
+\end_layout
+
+\begin_layout Plain Layout
+
+ toEnum = fromIntegral
+\end_layout
+
+\begin_layout Plain Layout
+
+ fromEnum = fromInteger .
+ truncate
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Enum Double where
+\end_layout
+
+\begin_layout Plain Layout
+
+ toEnum = fromIntegral
+\end_layout
+
+\begin_layout Plain Layout
+
+ fromEnum = fromInteger .
+ truncate
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Caracteres
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+instance Enum Char where ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Bounded Char where
+\end_layout
+
+\begin_layout Plain Layout
+
+ minBound = '
+\backslash
+0'
+\end_layout
+
+\begin_layout Plain Layout
+
+ maxBound = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Eq Char where
+\end_layout
+
+\begin_layout Plain Layout
+
+ c == c' = fromEnum c == fromEnum c'
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Ord Char where
+\end_layout
+
+\begin_layout Plain Layout
+
+ c <= c' = fromEnum c <= fromEnum c'
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+type String = [Char]
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Mónadas
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+fail, sequence, sequence_, mapM, mapM_, (=<<)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+class Functor f where
+\end_layout
+
+\begin_layout Plain Layout
+
+ fmap :: (a -> b) -> f a -> f b
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+class Monad m where {#- MINIMAL (>>=), return -#}
+\end_layout
+
+\begin_layout Plain Layout
+
+ (>>=) :: m a -> (a -> m b) -> m b
+\end_layout
+
+\begin_layout Plain Layout
+
+ (>>) :: m a -> m b -> m b
+\end_layout
+
+\begin_layout Plain Layout
+
+ return :: a -> m a
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ m >> k = m >>=
+\backslash
+_ -> k
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Section
+Tipos monádicos
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show)
+\end_layout
+
+\begin_layout Plain Layout
+
+data IO a = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+instance Monad IO where ...
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+Maybe, maybe, either, instance Functor IO, instance Monad IO, instance Functor
+ [], instance Monad []
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Note
+status open
+
+\begin_layout Plain Layout
+Complex, read
+\end_layout
+
+\begin_layout Plain Layout
+Eq a => Eq [a]
+\end_layout
+
+\begin_layout Plain Layout
+Ord a => Ord [a]
+\end_layout
+
+\begin_layout Plain Layout
+putStr
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\end_body
+\end_document