Tema 13: Programas interactivos
Informática (2016–17)
José A. Alonso Jiménez
Grupo de Lógica Computacional
Departamento de Ciencias de la Computación e I.A.
Universidad de Sevilla
IM Tema 13: Programas interactivos
Tema 13: Programas interactivos
1. Programas interactivos
2. El tipo de las acciones de entrada/salida
3. Acciones básicas
4. Secuenciación
5. Primitivas derivadas
6. Ejemplos de programas interactivos
Juego de adivinación interactivo
Calculadora aritmética
El juego de la vida
2 / 38
IM Tema 13: Programas interactivos
Programas interactivos
Programas interactivos
Los programas por lote no interactúan con los usuarios durante
su ejecución.
Los programas interactivos durante su ejecución pueden leer
datos del teclado y escribir resultados en la pantalla.
Problema:
Los programas interactivos tienen efectos laterales.
Los programa Haskell no tiene efectos laterales.
3 / 38
IM Tema 13: Programas interactivos
Programas interactivos
Ejemplo de programa interactivo
Especificación: El programa pide una cadena y dice el número de
caracteres que tiene.
Ejemplo de sesión:
*Main> longitudCadena
Escribe una cadena: "Hoy es lunes"
La cadena tiene 14 caracteres
Programa:
longitudCadena :: IO ()
longitudCadena = do putStr "Escribe una cadena: "
xs <- getLine
putStr "La cadena tiene "
putStr (show (length xs))
putStrLn " caracteres"
4 / 38
IM Tema 13: Programas interactivos
El tipo de las acciones de entrada/salida
El tipo de las acciones de entrada/salida
En Haskell se pueden escribir programas interactivos usando tipos
que distingan las expresiones puras de las acciones impuras que
tienen efectos laterales.
IO a es el tipo de las acciones que devuelven un valor del tipo a.
Ejemplos:
IO Char es el tipo de las acciones que devuelven un carácter.
IO () es el tipo de las acciones que no devuelven ningún valor.
5 / 38
IM Tema 13: Programas interactivos
Acciones básicas
Acciones básicas
getChar :: IO Char
La acción getChar lee un carácter del teclado, lo muestra en la
pantalla y lo devuelve como valor.
putChar :: c -> IO ()
La acción putChar c escribe el carácter c en la pantalla y no
devuelve ningún valor.
return a -> IO a
La acción return c devuelve el valor c sin ninguna interacción.
Ejemplo:
*Main> putChar 'b'
b*Main> it
()
6 / 38
IM Tema 13: Programas interactivos
Secuenciación
Secuenciación
Una sucesión de acciones puede combinarse en una acción
compuesta mediante expresiones do.
Ejemplo:
ejSecuenciacion :: IO (Char,Char)
ejSecuenciacion = do x <- getChar
getChar
y <- getChar
return (x,y)
Lee dos caracteres y devuelve el par formado por ellos. Por
ejemplo,
*Main> ejSecuenciacion
b f
('b','f')
7 / 38
IM Tema 13: Programas interactivos
Primitivas derivadas
Primitivas derivadas de lectura
Lectura de cadenas del teclado:
getLine :: IO String
getLine = do x <- getChar
Prelude
if x == '\n' then return []
else do xs <- getLine
return (x:xs)
8 / 38
IM Tema 13: Programas interactivos
Primitivas derivadas
Primitivas derivadas de escritura
Escritura de cadenas en la pantalla:
Prelude
putStr :: String -> IO ()
putStr []
= return ()
putStr (x:xs) = do putChar x
putStr xs
Escritura de cadenas en la pantalla y salto de línea:
Prelude
putStrLn :: String -> IO ()
putStrLn xs = do putStr xs
putChar '\n'
9 / 38
IM Tema 13: Programas interactivos
Primitivas derivadas
Primitivas derivadas: lista de acciones
Ejecución de una lista de acciones:
Prelude
sequence_ :: [IO a] -> IO ()
sequence_ []
= return ()
sequence_ (a:as) = do a
sequence_ as
Por ejemplo,
*Main> sequence_ [putStrLn "uno", putStrLn "dos"]
uno
dos
*Main> it
()
10 / 38
IM Tema 13: Programas interactivos
Primitivas derivadas
Ejemplo de programa con primitivas derivadas
Especificación: El programa pide una cadena y dice el número de
caracteres que tiene.
Ejemplo de sesión:
*Main> longitudCadena
Escribe una cadena: "Hoy es lunes"
La cadena tiene 14 caracteres
Programa:
longitudCadena :: IO ()
longitudCadena = do putStr "Escribe una cadena: "
xs <- getLine
putStr "La cadena tiene "
putStr (show (length xs))
putStrLn " caracteres"
11 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Juego de adivinación interactivo
Tema 13: Programas interactivos
1. Programas interactivos
2. El tipo de las acciones de entrada/salida
3. Acciones básicas
4. Secuenciación
5. Primitivas derivadas
6. Ejemplos de programas interactivos
Juego de adivinación interactivo
Calculadora aritmética
El juego de la vida
12 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Juego de adivinación interactivo
Juego de adivinación interactivo
Descripción: El programa le pide al jugador humano que piense
un número entre 1 y 100 y trata de adivinar el número que ha
pensado planteándole conjeturas a las que el jugador humano
responde con mayor, menor o exacto según que el número
pensado sea mayor, menor o igual que el número conjeturado por
la máquina.
Ejemplo de sesión:
Main> juego
Piensa un numero entre el 1 y el 100.
Es 50? [mayor/menor/exacto] mayor
Es 75? [mayor/menor/exacto] menor
Es 62? [mayor/menor/exacto] mayor
Es 68? [mayor/menor/exacto] exacto
Fin del juego
13 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Juego de adivinación interactivo
Juego interactivo
Programa:
juego :: IO ()
juego =
do putStrLn "Piensa un numero entre el 1 y el 100."
adivina 1 100
putStrLn "Fin del juego"
adivina :: Int -> Int -> IO ()
adivina a b =
do putStr ("Es " ++ show conjetura ++ "? [mayor/menor/exacto] ")
s <- getLine
case s of
"mayor" -> adivina (conjetura+1) b
"menor" -> adivina a (conjetura-1)
"exacto" -> return ()
_
-> adivina a b
where
conjetura = (a+b) `div` 2
14 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Juego de adivinación interactivo
Segundo juego de adivinación interactivo
Descripción: En el segundo juego la máquina genera un número
aleatorio entre 1 y 100 y le pide al jugador humano que adivine el
número que ha pensado planteándole conjeturas a las que la
máquina responde con mayor, menor o exacto según que el
número pensado sea mayor, menor o igual que el número
conjeturado por el jugador humano.
Ejemplo de sesión:
Main> juego2
Tienes que adivinar un numero entre 1 y 100
Escribe un numero: 50
es bajo.
Escribe un numero: 75
es alto.
Escribe un numero: 62
Exactamente
15 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Juego de adivinación interactivo
Segundo juego interactivo
Programa:
import System.Random (randomRIO)
juego2 :: IO ()
juego2 = do n <- randomRIO (1::Int,100)
putStrLn "Tienes que adivinar un numero entre 1 y 100"
adivina' n
adivina' :: Int -> IO ()
adivina' n =
do putStr "Escribe un numero: "
c <- getLine
let x = read c
case (compare x n) of
LT -> do putStrLn " es bajo."
adivina' n
GT -> do putStrLn " es alto."
adivina' n
EQ -> putStrLn " Exactamente"
16 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Tema 13: Programas interactivos
1. Programas interactivos
2. El tipo de las acciones de entrada/salida
3. Acciones básicas
4. Secuenciación
5. Primitivas derivadas
6. Ejemplos de programas interactivos
Juego de adivinación interactivo
Calculadora aritmética
El juego de la vida
17 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Acciones auxiliares
Importaciones
import I1M.Analizador
import System.IO
Escritura de caracteres sin eco:
getCh :: IO Char
getCh = do hSetEcho stdin False
c <- getChar
hSetEcho stdin True
return c
Limpieza de la pantalla:
limpiaPantalla :: IO ()
limpiaPantalla = putStr "\ESC[2J"
18 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Acciones auxiliares
Escritura en una posición:
type Pos = (Int,Int)
irA :: Pos -> IO ()
irA (x,y) = putStr ("\ESC[" ++
show y ++ ";" ++ show x ++
"H")
escribeEn :: Pos -> String -> IO ()
escribeEn p xs = do irA p
putStr xs
En las funciones limpiaPantalla e irA se han usado códigos de
escape ANSI
19 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Calculadora
calculadora :: IO ()
calculadora = do limpiaPantalla
escribeCalculadora
limpiar
escribeCalculadora :: IO ()
escribeCalculadora =
do limpiaPantalla
sequence_ [escribeEn (1,y) xs
| (y,xs) <- zip [1..13] imagenCalculadora]
putStrLn ""
20 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Calculadora
imagenCalculadora :: [String]
imagenCalculadora = ["+---------------+",
"|
|",
"+---+---+---+---+",
"| q | c | d | = |",
"+---+---+---+---+",
"| 1 | 2 | 3 | + |",
"+---+---+---+---+",
"| 4 | 5 | 6 | - |",
"+---+---+---+---+",
"| 7 | 8 | 9 | * |",
"+---+---+---+---+",
"| 0 | ( | ) | / |",
"+---+---+---+---+"]
Los primeros cuatro botones permiten escribir las órdenes:
q para salir (’quit’),
c para limpiar la agenda (’clear’),
d para borrar un carácter (’delete’) y
= para evaluar una expresión.
Los restantes botones permiten escribir las expresiones.
21 / 38
IM Tema 13: Programas interactivos
Ejemplos de programas interactivos
Calculadora aritmética
Calculadora
limpiar :: IO ()
limpiar = calc ""
calc :: String -> IO ()
calc xs = do escribeEnPantalla xs
c <- getCh
if elem c botones
then procesa c xs
else do calc xs
escribeEnPantalla xs =
do escribeEn (3,2) "
"
escribeEn (3,2) (reverse (take 13 (reverse xs)))
22 / 38
IM Tema 13: Programas interactivos
Comentarios de: Tema 13: Programas interactivos - Informática (2016–17) (0)
No hay comentarios