aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pia/n.lyx35
-rw-r--r--pia/n4.lyx904
-rw-r--r--pia/n5.lyx106
-rw-r--r--pia/n7.lyx809
4 files changed, 1707 insertions, 147 deletions
diff --git a/pia/n.lyx b/pia/n.lyx
index fcf44ce..908793a 100644
--- a/pia/n.lyx
+++ b/pia/n.lyx
@@ -215,6 +215,27 @@ https://www.haskell.org/onlinereport/haskell2010/haskell.html
.
\end_layout
+\begin_layout Itemize
+Haskell Wiki.
+
+\emph on
+Monad laws
+\emph default
+.
+ Recuperado de
+\begin_inset Flex URL
+status open
+
+\begin_layout Plain Layout
+
+https://wiki.haskell.org/Monad_laws
+\end_layout
+
+\end_inset
+
+ el 5 de diciembre de 2022.
+\end_layout
+
\begin_layout Chapter
Introducción
\end_layout
@@ -315,5 +336,19 @@ filename "n6.lyx"
\end_layout
+\begin_layout Chapter
+Entrada y salida
+\end_layout
+
+\begin_layout Standard
+\begin_inset CommandInset include
+LatexCommand input
+filename "n7.lyx"
+
+\end_inset
+
+
+\end_layout
+
\end_body
\end_document
diff --git a/pia/n4.lyx b/pia/n4.lyx
index 68a289f..c1afdfa 100644
--- a/pia/n4.lyx
+++ b/pia/n4.lyx
@@ -359,17 +359,7 @@ reservedop =~
\end_layout
\begin_layout Standard
-Las variables pueden estar en espacios de nombres jerárquicos:
-\begin_inset Note Comment
-status open
-
-\begin_layout Plain Layout
-tyvar=varid, tycon=tycls=conid, modid=qtycon=qtycls=qconid
-\end_layout
-
-\end_inset
-
-
+Las variables pueden estar en espacios de nombres aparentemente jerárquicos:
\end_layout
\begin_layout Standard
@@ -411,7 +401,16 @@ qconsym =~ (<conid>
\end_layout
\begin_layout Standard
-Se escriben como sigue:
+Realmente sólo se distingue entre el nombre de la variable, detrás del último
+
+\family typewriter
+.
+\family default
+, y el del módulo, antes del
+\family typewriter
+.
+\family default
+, y no hay relación jerárquica entre módulos.
\end_layout
\begin_layout Standard
@@ -904,26 +903,7 @@ contexto
nombre.
Las expresiones se evalúan en un cierto contexto, y describen un valor
que depende de este.
- Inicialmente el contexto global incluye las
-\series bold
-operaciones primitivas
-\series default
- incluidas en el evaluador, como las operaciones aritméticas básicas y las
- incluidas en
-\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
\begin_layout Standard
@@ -1104,6 +1084,16 @@ qconop = gconsym /
gconsym = qconsym
\end_layout
+\begin_layout Plain Layout
+
+cname = var / con
+\end_layout
+
+\begin_layout Plain Layout
+
+qop = qvarop / qconop
+\end_layout
+
\end_inset
@@ -1128,6 +1118,21 @@ s y una función con nombre normal como operador poniéndola entre comillas
Se pueden definir nuevos operadores.
\end_layout
+\begin_layout Standard
+En el resto del capítulo cuando se menciona un nombre concreto, salvo que
+ se indique lo contrario, se entiende que pertenece al módulo
+\family typewriter
+\lang english
+Prelude
+\family default
+\lang spanish
+, el
+\series bold
+preludio estándar
+\series default
+, cuyos vínculos están por defecto en el contexto global.
+\end_layout
+
\begin_layout Section
Tipos
\end_layout
@@ -1206,7 +1211,7 @@ Un tipo puede ser un
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.
+ un número fijo de parámetros de tipo.
\end_layout
\begin_layout Standard
@@ -1282,8 +1287,10 @@ polimórfico
\begin_layout Standard
Tipos primitivos en el
\family typewriter
+\lang english
Prelude
\family default
+\lang spanish
:
\end_layout
@@ -1519,6 +1526,9 @@ gtycon /=
\end_layout
\begin_layout Standard
+\begin_inset Newpage pagebreak
+\end_inset
+
Podemos definir nuevos tipos para aumentar la seguridad de los programas:
\end_layout
@@ -1637,8 +1647,10 @@ simpletype
.
El
\family typewriter
+\lang english
Prelude
\family default
+\lang spanish
define
\family typewriter
data Bool = False | True
@@ -2764,7 +2776,7 @@ a
\emph default
equivale a
\family typewriter
-Prelude.negate
+negate
\emph on
a
\family default
@@ -2791,11 +2803,11 @@ integer
\family default
equivalen a
\family typewriter
-Prelude.fromInteger (
+fromInteger (
\emph on
x
\emph default
- :: Prelude.Integer)
+ :: Integer)
\family default
, siendo
\family typewriter
@@ -2809,7 +2821,7 @@ float
\family default
a
\family typewriter
-Prelude.fromRational (
+fromRational (
\emph on
x
\emph default
@@ -3837,7 +3849,7 @@ e1
\family default
equivale a
\family typewriter
-Prelude.enumFrom
+enumFrom
\emph on
e1
\family default
@@ -3856,7 +3868,7 @@ e2
\family default
a
\family typewriter
-Prelude.enumFromThen
+enumFromThen
\emph on
e1 e2
\family default
@@ -3875,7 +3887,7 @@ e3
\family default
a
\family typewriter
-Prelude.enumFromTo
+enumFromTo
\emph on
e1 e3
\family default
@@ -3898,7 +3910,7 @@ e3
\family default
a
\family typewriter
-Prelude.enumFromThenTo
+enumFromThenTo
\emph on
e1 e2 e3
\family default
@@ -4248,6 +4260,169 @@ e
.
\end_layout
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+lexp /=
+\begin_inset Quotes cld
+\end_inset
+
+do
+\begin_inset Quotes crd
+\end_inset
+
+
+\begin_inset Quotes cld
+\end_inset
+
+{
+\begin_inset Quotes cld
+\end_inset
+
+ stmts
+\begin_inset Quotes cld
+\end_inset
+
+}
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+stmts = *stmt exp [
+\begin_inset Quotes cld
+\end_inset
+
+;
+\begin_inset Quotes crd
+\end_inset
+
+]
+\end_layout
+
+\begin_layout Plain Layout
+
+stmt = (exp / pat
+\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
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+do {
+\emph on
+exp
+\emph default
+ }
+\family default
+ equivale a
+\family typewriter
+\emph on
+exp
+\family default
+\emph default
+, que debe tener tipo
+\family typewriter
+m a
+\family default
+ para algún
+\family typewriter
+m
+\family default
+ de clase
+\family typewriter
+Monad
+\family default
+ y algún
+\family typewriter
+a
+\family default
+;
+\family typewriter
+do {
+\emph on
+exp
+\emph default
+;
+\emph on
+rest
+\emph default
+ }
+\family default
+ equivale a
+\family typewriter
+\emph on
+exp
+\emph default
+ >> do {
+\emph on
+rest
+\emph default
+ }
+\family default
+, y
+\family typewriter
+do {
+\emph on
+pat
+\emph default
+ <-
+\emph on
+exp
+\emph default
+;
+\emph on
+rest
+\emph default
+}
+\family default
+ equivale a
+\family typewriter
+\emph on
+exp
+\emph default
+ >>=
+\backslash
+
+\emph on
+pat
+\emph default
+ -> do {
+\emph on
+rest
+\emph default
+ }
+\family default
+.
+\end_layout
+
\begin_layout Section
Definiciones
\end_layout
@@ -4550,5 +4725,652 @@ infix
).
\end_layout
+\begin_layout Section
+Módulos
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+module /=
+\begin_inset Quotes cld
+\end_inset
+
+module
+\begin_inset Quotes crd
+\end_inset
+
+ qconid [exports]
+\begin_inset Quotes cld
+\end_inset
+
+where
+\begin_inset Quotes crd
+\end_inset
+
+ body
+\end_layout
+
+\begin_layout Plain Layout
+
+exports =
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [export *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ export) [
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+export = qvar / qconid [
+\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 crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [cname *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ cname)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+]
+\end_layout
+
+\begin_layout Plain Layout
+
+ / qconid [
+\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 crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [qvar *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ qvar)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+]
+\end_layout
+
+\begin_layout Plain Layout
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+module
+\begin_inset Quotes crd
+\end_inset
+
+ qconid
+\end_layout
+
+\begin_layout Plain Layout
+
+cname = var / con
+\end_layout
+
+\begin_layout Plain Layout
+
+body /=
+\begin_inset Quotes cld
+\end_inset
+
+{
+\begin_inset Quotes cld
+\end_inset
+
+ impdecls [
+\begin_inset Quotes cld
+\end_inset
+
+;
+\begin_inset Quotes crd
+\end_inset
+
+ topdecls]
+\begin_inset Quotes cld
+\end_inset
+
+}
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+impdecls = impdecl *(
+\begin_inset Quotes cld
+\end_inset
+
+;
+\begin_inset Quotes crd
+\end_inset
+
+ impdecl)
+\end_layout
+
+\begin_layout Plain Layout
+
+impdecl =
+\begin_inset Quotes cld
+\end_inset
+
+import
+\begin_inset Quotes crd
+\end_inset
+
+ [
+\begin_inset Quotes cld
+\end_inset
+
+qualified
+\begin_inset Quotes crd
+\end_inset
+
+] qconid [
+\begin_inset Quotes cld
+\end_inset
+
+as
+\begin_inset Quotes crd
+\end_inset
+
+ qconid] [impspec]
+\end_layout
+
+\begin_layout Plain Layout
+
+impspec = [
+\begin_inset Quotes cld
+\end_inset
+
+hiding
+\begin_inset Quotes crd
+\end_inset
+
+]
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [import *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ import)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+import = var / qconid[
+\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 crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [cname *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ cname)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ / qconid[
+\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 crd
+\end_inset
+
+ /
+\begin_inset Quotes cld
+\end_inset
+
+(
+\begin_inset Quotes cld
+\end_inset
+
+ [var *(
+\begin_inset Quotes cld
+\end_inset
+
+,
+\begin_inset Quotes crd
+\end_inset
+
+ var)]
+\begin_inset Quotes cld
+\end_inset
+
+)
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Haskell organiza los elementos en módulos, uno por fichero, cada uno con
+ un nombre único y un contexto global formado por los vínculos establecidos
+ en el módulo y los que se importan de otros.
+
+\end_layout
+
+\begin_layout Standard
+Una
+\series bold
+entidad
+\series default
+ es un vínculo importado o exportado por un módulo, con un nombre que no
+ incluye el nombre del módulo y un valor.
+\end_layout
+
+\begin_layout Standard
+Se exportan las entidades indicadas por
+\family typewriter
+exports
+\family default
+:
+\family typewriter
+\emph on
+qvar
+\family default
+\emph default
+ para una variable,
+\family typewriter
+\emph on
+qconid
+\family default
+\emph default
+ para un tipo o clase,
+\family typewriter
+\emph on
+qconid
+\emph default
+(..)
+\family default
+ para el tipo y todos sus constructores o la clase y todos sus métodos;
+
+\family typewriter
+\emph on
+qconid
+\emph default
+(
+\emph on
+cname
+\emph default
+,
+\family default
+...
+\family typewriter
+)
+\family default
+ para el tipo y los constructores indicados, y
+\family typewriter
+\emph on
+qconid
+\emph default
+(
+\emph on
+qvar
+\emph default
+,
+\family default
+...
+\family typewriter
+)
+\family default
+ para el tipo y los métodos indicados.
+ Si no hay un
+\family typewriter
+exports
+\family default
+, se exportan todos los vínculos definidos en el módulo.
+\end_layout
+
+\begin_layout Standard
+Una
+\family typewriter
+impdecl
+\family default
+ importa entidades del módulo
+\family typewriter
+qconid
+\family default
+, por defecto todas las que este importa, pero
+\family typewriter
+impspec
+\family default
+ permite importar sólo los vínculos de los
+\family typewriter
+import
+\family default
+, con la misma semántica que los
+\family typewriter
+export
+\family default
+, o sólo los que no están en los
+\family typewriter
+import
+\family default
+ si se indica
+\family typewriter
+hiding
+\family default
+.
+ Añadir
+\family typewriter
+qualified
+\family default
+ hace que las entidades se importen con nombre
+\family typewriter
+\emph on
+módulo
+\emph default
+.
+\emph on
+entidad
+\family default
+\emph default
+, donde el
+\family typewriter
+\emph on
+módulo
+\family default
+\emph default
+ es el nombre del módulo del que se importa o el que se indica después de
+
+\family typewriter
+as
+\family default
+ si aparece.
+\end_layout
+
+\begin_layout Standard
+Algunos programadores prefieren usar
+\family typewriter
+qualified
+\family default
+ en todos los
+\family typewriter
+import
+\family default
+, haciendo explícito el origen de cada nombre y usando
+\family typewriter
+as
+\family default
+ si hace falta para acortar el nombre, mientras que otros prefieren nombres
+ cortos y usan
+\family typewriter
+qualified
+\family default
+ o
+\family typewriter
+hiding
+\family default
+ según sea necesario para evitar conflictos de nombres.
+\end_layout
+
+\begin_layout Standard
+Los módulos permiten crear tipos de datos abstractos, pues exportar un tipo
+ sin constructores hace que este solo se pueda usar fuera del módulo a través
+ de las operaciones exportadas, permitiendo cambiar la representación del
+ tipo sin afectar a sus usuarios.
+\end_layout
+
+\begin_layout Standard
+Haskell no especifica una relación entre nombres de módulo y de fichero,
+ pero GHC busca el módulo
+\family typewriter
+\emph on
+A1
+\emph default
+.
+\family default
+...
+\family typewriter
+.
+\emph on
+An
+\family default
+\emph default
+ en
+\family typewriter
+\emph on
+A1
+\emph default
+/
+\family default
+...
+\family typewriter
+/
+\emph on
+An
+\emph default
+.hs
+\family default
+ en el directorio raíz del programa (el directorio actual si se usa GHCi)
+ y una serie de directorios predefinidos.
+
+\end_layout
+
+\begin_layout Standard
+Un
+\series bold
+preludio
+\series default
+ es un módulo que se importa por defecto en los demás como si hubiera un
+
+\family typewriter
+import
+\emph on
+Preludio
+\family default
+\emph default
+, salvo que haya un
+\family typewriter
+impdecl
+\family default
+ explícito para ese preludio.
+ El único es
+\family typewriter
+\lang english
+Prelude
+\family default
+\lang spanish
+, con
+\series bold
+operaciones primitivas
+\series default
+ incluidas en el evaluador, como las operaciones aritméticas básicas, y
+ tipos y funciones de utilidad.
+\end_layout
+
\end_body
\end_document
diff --git a/pia/n5.lyx b/pia/n5.lyx
index aa30ac4..c343e81 100644
--- a/pia/n5.lyx
+++ b/pia/n5.lyx
@@ -1175,7 +1175,6 @@ s
\begin_inset Formula $\bot$
\end_inset
-.
y, cuando se evalúa, imprime el error
\family typewriter
\emph on
@@ -1793,111 +1792,6 @@ type String = [Char]
\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
-
-\begin_layout Plain Layout
-
-\end_layout
-
-\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
diff --git a/pia/n7.lyx b/pia/n7.lyx
new file mode 100644
index 0000000..0e78e74
--- /dev/null
+++ b/pia/n7.lyx
@@ -0,0 +1,809 @@
+#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
+\begin_inset listings
+inline false
+status open
+
+\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
+
+ fail :: String -> m a
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ m >> k = m >>=
+\backslash
+_ -> k
+\end_layout
+
+\begin_layout Plain Layout
+
+ fail s = error s
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Note Comment
+status open
+
+\begin_layout Plain Layout
+Functor, sequence, mapM, (=<<), Maybe, maybe, Either, either, instance Functor
+ IO, instance Monad IO, instance Functor [], instance Monad [], IOError,
+ ioError, userError, catch, readIO, readLn
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonada
+\backslash
+url{https://stackoverflow.com/questions/3870088/a-monad-is-just-a-monoid-in-the-c
+ategory-of-endofunctors-whats-the-problem#3870310}
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonadb
+\backslash
+url{http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html}
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonadc
+\backslash
+url{https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-t
+utorial-fallacy/}
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonadd
+\backslash
+url{https://blog.plover.com/prog/burritos.html}
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonade
+\backslash
+url{https://wiki.haskell.org/All_About_Monads}
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+urldef
+\backslash
+urlmonadf
+\backslash
+url{https://wiki.haskell.org/Monad}
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Una
+\series bold
+mónada
+\series default
+ es una instancia de
+\family typewriter
+Monad
+\family default
+ con las siguientes propiedades:
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Una mónada en
+\begin_inset Formula $X$
+\end_inset
+
+ es un monoide en la categoría de los endofuntores de
+\begin_inset Formula $X$
+\end_inset
+
+, con el producto reemplazado por la composición de endofuntores y el conjunto
+ unidad por el endofuntor identidad (
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urlmonada
+\end_layout
+
+\end_inset
+
+).
+ Una mónada es un como un burrito (
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urlmonadc
+\end_layout
+
+\end_inset
+
+,
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urlmonadd
+\end_layout
+
+\end_inset
+
+).
+ No voy a explicar la intuición de qué es una mónada porque en el examen
+ sólo entra la definición formal e IO, pero hay un tutorial muy bueno en
+ la Wiki de Haskell (
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urlmonade
+\end_layout
+
+\end_inset
+
+) y una explicación resumida (
+\begin_inset ERT
+status open
+
+\begin_layout Plain Layout
+
+
+\backslash
+urlmonadf
+\end_layout
+
+\end_inset
+
+).
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Enumerate
+Identidad por la izquierda:
+\family typewriter
+return a >>= h = ha
+\family default
+.
+\end_layout
+
+\begin_layout Enumerate
+Identidad por la derecha:
+\family typewriter
+m >>= return = m
+\family default
+.
+\end_layout
+
+\begin_layout Enumerate
+Asociatividad:
+\family typewriter
+(m >>= g) >>= h = m >>= (
+\backslash
+x -> g x >>= h)
+\family default
+.
+\end_layout
+
+\begin_layout Standard
+Una
+\series bold
+mónada de E/S
+\series default
+ es una mónada
+\family typewriter
+m
+\family default
+ que además tiene operaciones
+\family typewriter
+putChar :: Char -> m ()
+\family default
+ y
+\family typewriter
+getChar :: m Char
+\family default
+, como
+\family typewriter
+IO
+\family default
+.
+
+\family typewriter
+IO a
+\family default
+ es el tipo de las acciones que pueden realizar operaciones de E/S y devuelven
+ un resultado de tipo
+\family typewriter
+a
+\family default
+.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\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
+
+\family typewriter
+return
+\emph on
+a
+\family default
+\emph default
+ es una acción que no hace nada y devuelve
+\family typewriter
+\emph on
+a
+\family default
+\emph default
+, y
+\family typewriter
+\emph on
+m
+\emph default
+ >>=
+\emph on
+h
+\family default
+\emph default
+ es una que ejecuta
+\family typewriter
+\emph on
+m
+\family default
+\emph default
+, le pasa el resultado a
+\family typewriter
+\emph on
+h
+\family default
+\emph default
+ y devuelve el resultado de ejecutar la acción devuelta por
+\family typewriter
+\emph on
+h
+\family default
+\emph default
+, permitiendo secuenciar acciones.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+sequence_ :: Monad m => [m a] -> m ()
+\end_layout
+
+\begin_layout Plain Layout
+
+sequence_ = foldr (>>) (return ())
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+mapM_ :: Monad m => (a -> m b) -> [a] -> m [b]
+\end_layout
+
+\begin_layout Plain Layout
+
+mapM_ f as = sequence_ (map f as)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Podemos definir (aunque no está en el
+\family typewriter
+Prelude
+\family default
+):
+\begin_inset Foot
+status open
+
+\begin_layout Plain Layout
+Está en
+\family typewriter
+Control.Monad.Extra
+\family default
+ y se llama
+\family typewriter
+skip
+\family default
+.
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+done :: Monad m => m ()
+\end_layout
+
+\begin_layout Plain Layout
+
+done = return ()
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+putChar
+\family default
+ imprime un caracter,
+\family typewriter
+getChar
+\family default
+ lee uno de la entrada estándar y
+\family typewriter
+getContents
+\family default
+ lee toda la entrada estándar en una
+\family typewriter
+String
+\family default
+ de forma perezosa según se va necesitando.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+putChar :: Char -> IO ()
+\end_layout
+
+\begin_layout Plain Layout
+
+putChar = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+getChar :: IO Char
+\end_layout
+
+\begin_layout Plain Layout
+
+getChar = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+getContents :: IOString
+\end_layout
+
+\begin_layout Plain Layout
+
+getContents = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+putStr, putStrLn :: String -> IO ()
+\end_layout
+
+\begin_layout Plain Layout
+
+putStr s = map_ putChar s
+\end_layout
+
+\begin_layout Plain Layout
+
+putStrLn s = putStr s >> putStr
+\begin_inset Quotes cld
+\end_inset
+
+
+\backslash
+n
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+print :: Show a => a -> IO ()
+\end_layout
+
+\begin_layout Plain Layout
+
+print x = putStrLn (show x)
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+getLine :: IO String
+\end_layout
+
+\begin_layout Plain Layout
+
+getLine = getChar >>=
+\backslash
+c -> if c == '
+\backslash
+n' then return
+\begin_inset Quotes cld
+\end_inset
+
+
+\begin_inset Quotes crd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+ else getLine >>=
+\backslash
+s -> return (c:s)
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+interact
+\emph on
+f
+\family default
+\emph default
+ desactiva el
+\emph on
+buffering
+\emph default
+ de la entrada y salida estándar, le pasa la entrada estándar a
+\family typewriter
+\emph on
+f
+\family default
+\emph default
+ y va imprimiendo el valor devuelto por la función, evaluándolo y pidiendo
+ caracteres de la entrada según sea necesario.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+interact :: (String -> String) -> IO ()
+\end_layout
+
+\begin_layout Plain Layout
+
+interact f = hSetBuffering stdin NoBuffering >>=
+\end_layout
+
+\begin_layout Plain Layout
+
+ hSetBuffering stdout NoBuffering >>=
+\end_layout
+
+\begin_layout Plain Layout
+
+ s <- getContents >>= putStr (f s)
+\end_layout
+
+\begin_layout Plain Layout
+
+ where hSetBuffering = ...
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Newpage pagebreak
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\family typewriter
+readFile
+\family default
+ lee el contenido de un fichero de forma perezosa,
+\family typewriter
+writeFile
+\family default
+ escribe un fichero y
+\family typewriter
+appendFile
+\family default
+ añade contenido al final de uno.
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+type FilePath = String
+\end_layout
+
+\begin_layout Plain Layout
+
+readFile :: FilePath -> IO String
+\end_layout
+
+\begin_layout Plain Layout
+
+readFile = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+\end_layout
+
+\begin_layout Plain Layout
+
+writeFile, appendFile :: FilePath -> String -> IO ()
+\end_layout
+
+\begin_layout Plain Layout
+
+writeFile = ...
+\end_layout
+
+\begin_layout Plain Layout
+
+appendFile = ...
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Un programa en Haskell es una colección de módulos de los que uno es el
+ principal y tiene un vínculo
+\family typewriter
+main :: IO ()
+\family default
+, que se ejecuta al ejecutar el programa.
+\end_layout
+
+\end_body
+\end_document