Escolar Documentos
Profissional Documentos
Cultura Documentos
Program A Cao Haskell
Program A Cao Haskell
ndice
CAPTULO 1 Programao em Haskell__________________________________ 4
1.1 Expresses e Funes _________________________________________________ 4
1.2. Inteiros____________________________________________________________ 6
1.3 Booleanos _________________________________________________________ 8
1.4 Caracteres e Strings __________________________________________________ 9
1.5 Nmeros em Ponto Flutuante __________________________________________ 11
1.6 Tuplas ____________________________________________________________ 12
1.7 Funes Recursivas _________________________________________________ 13
1.8 Exemplos _________________________________________________________ 15
CAPTULO 2 Listas em Haskell _______________________________________ 18
2.1 Listas_____________________________________________________________ 18
2.2 Operadores ________________________________________________________ 19
2.3 Funes sobre Listas_________________________________________________ 20
2.4 List Comprehensions ________________________________________________ 24
2.5 Definies_________________________________________________________ 26
2.6 Outras Funes teis sobre Listas ______________________________________ 30
2.7 Listas Infinitas _____________________________________________________ 33
2.8 Erros _____________________________________________________________ 35
CAPTULO 3 Conceitos Avanados ____________________________________ 37
3.1 Currying __________________________________________________________ 37
3.2 Composio de Funes ______________________________________________ 39
3.3 Expresses Lambda _________________________________________________ 41
CAPTULO 4 Classes de Tipo _________________________________________ 43
4.1 Classes de Tipo_____________________________________________________ 43
4.2 Classes Derivadas___________________________________________________ 45
4.3 Contexto __________________________________________________________ 46
4.4 Algumas Classes Importantes__________________________________________ 47
4.4.1 Enum ___________________________________________________________ 47
4.4.2 Read e Show _____________________________________________________ 48
4.4.3 Classes de Nmeros________________________________________________ 48
2
Haskell> 4 + 3
7
ou
---
exemplo.hs
--
--
idade :: Int
idade = 17
maiorDeIdade :: Bool
maiorDeIdade = (idade>=18)
quadrado x = x * x
mini a b
| a <= b
=a
| otherwise
=b
Haskell> quadrado 2
4
A funo mini devolve o menor valor entre os seus dois argumentos, que so
valores do tipo Int. Para se obter a resposta, testam-se os valores para se decidir qual o
menor. Para isso so usados guards que so expresses booleanas iniciadas por uma barra |.
No exemplo, se o valor de a menor ou igual que b a resposta a, seno passa-se para o
prximo guard. Temos ento a expresso otherwise, que sempre possui a resposta se todos
os outros guards falharem. Ex:
Potncia: 2^4 16
div
mod
abs
Qualquer operador pode ser usado como funo, e qualquer funo pode ser usada
como um operador, basta incluir o operador entre parnteses (), e a funo entre crases ``.
Ex:
Haskell> (+) 2 3
5
Haskell> 10 `mod` 3
1
O programador pode definir os seus prprios operadores em scripts:
=a
=b
Ex:
Haskell> 10 &&& 3
3
Pode-se trabalhar com ordenao e igualdade com os nmeros inteiros, assim como
com todos os tipos bsicos. As funes de ordenao e igualdade tem como argumento dois
nmeros inteiros e devolvem um valor do tipo Bool:
>
Maior que
>=
Maior ou igual
==
Igual
/=
Diferente
<=
Menor ou igual
<
Menor
Ex:
Haskell> 29 > 15
True
1.3 Booleanos
O tipo Bool o tipo dos valores booleanos True (Verdadeiro) ou False (Falso).
Os operadores booleanos so:
&&
||
ou
not
negao
-- ou exclusivo
ouEx :: Bool -> Bool -> Bool
ouEx x y = (x || y) && not (x && y)
ouEx True x
= not x
ouEx False x
=x
Este tipo de definio utiliza mais de uma equao. No exemplo, na primeira linha
da definio, se for passado um valor True e um outro valor qualquer, a resposta ser a
negao deste valor. Se no ocorrer este caso, passa-se para a segunda linha em que se
passa como argumento um valor False e um outro valor qualquer, que ser a resposta.
\t
Tabulao
\n
Nova linha
Aspas simples ()
Aspas duplas ()
\\
Barra (\)
Haskell> a < z
True
Haskell> A< a
True
Al Mundo!!
Haskell
Ex:
10
Isto quer dizer que o tipo String um sinnimo de uma lista de caracteres. Ex:
Existe em Haskell o tipo Float, que trabalha com nmeros fracionrios que so
representados em ponto flutuante.
Pode-se escrever os nmeros com casas decimais ou utilizando notao cientfica;
231.6e-2 que significa 231.61 10-2, ou simplesmente 2.3161. O tipo Float alm de
aceitar os operadores (+, - , *, ^, = =, /=, <=,>=, <, >) vistos anteriormente, possui algumas
funes prprias:
11
Diviso
**
Exponenciao, x ** x = xy
log
Logaritmo base e
logBase
read
show
sqrt
Raiz quadrada
fromInt
pi
Float
1.6 Tuplas
Uma tupla em Haskell uma agregao de um ou mais componentes. Estes
componentes podem ser de tipos diferentes. As tuplas so representadas em scripts por
listas de componentes separados por vrgula, entre parnteses. O tipo de uma tupla parece
uma tupla, mas possui tipos como componentes.
Ex:
12
Ento:
Uma funo recursiva uma funo que chama a ela mesma. Grande parte das
definies em Haskell sero recursivas, principalmente as que necessitam de algum tipo de
repetio. Uma definio recursiva clssica a do fatorial de um nmero inteiro positivo:
O fatorial de um nmero inteiro positivo pode ser dividido em dois casos:
Ento:
=1
(regra 1)
fatorial n
= n * fatorial (n-1)
(regra 2)
Exemplo de avaliao:
fatorial 3
= 3 * (fatorial 2)
(2)
= 3 * 2 * (fatorial 1)
(2)
= 3 * 2 * 1 * (fatorial 0)
(2)
=3*2*1*1
(1)
=6
Multiplicao
13
soma n seria
aluno 1 + aluno 2 + ... + aluno (n-1) + aluno n
Tem-se ento:
= aluno 1
soma n
Na segunda linha da definio tem-se que usar a funo fromInt para transformar o
valor n que tem tipo Int, em Float, pois o tipo do operador de diviso (/) :: Float -> Float
-> Float.
14
Nesta parte do texto analisa-se um exemplo mais extenso, usando as funes aluno
e media explicadas anteriormente. O objetivo criar uma funo que gere uma tabela
mostrando o nmero de todos os alunos e suas respectivas notas. No final da tabela deve
aparecer a mdia das notas. Exemplo:
Aluno
Nota
7.5
10
6.3
cabealho :: String
cabealho = Aluno
Nota\n
15
Para se imprimir as notas, devese imprimir um aluno por linha. Isto pode ser
definido recursivamente utilizando uma outra funo
imprimeAlunos 1
= imprimeAluno 1
imprimeAlunos n
++ show (aluno n) ++ \n
16
cabealho :: String
cabealho = Aluno
Nota\n
= imprimeAluno 1
imprimeAlunos n
++ show (aluno n) ++ \n
= aluno 1
soma n
17
[1, 2, 3, 4]
:: [Int]
[H, a, s, k, e, l, l]
:: [Char]
:: [Bool]
Pode-se trabalhar tambm com listas de listas, listas de tuplas e listas de funes
(desde que as funes tenham o mesmo tipo):
:: [[Int]]
:: [(Int, Char)]
Um outro caso so as listas vazias, [], que no possuem elementos e podem ser de
qualquer tipo:
[]
:: [Bool]
[]
:: [Float]
[]
Haskell > [1 .. 6]
18
Haskell > [4 .. 2]
[]
2.2 Operadores
O operador (:) o operador de construo de listas. Toda a lista construda atravs
deste operador, de elementos e de uma lista.
[1]
= 1 : []
[1, 2, 3, 4]
= 1 : 2 : 3 : 4 : []
19
Onde t uma varivel de tipo que pode ser substituda por qualquer tipo (Int, Char,
etc...). O conceito de polimorfismo ser esclarecido em maior profundidade no decorrer do
texto.
Outro operador para listas o de concatenao (++):
Aqui se usa a letra t como varivel de tipo. Porm pode-se usar qualquer letra
minscula.
Na maioria das definies sobre listas ir se usar a recurso para se percorrer todos
os elementos. Uma funo simples seria a funo para somar todos os elementos de uma
lista de nmeros inteiros:
20
somaLista []
=0
(1)
somaLista (a:x)
= a + somaLista x
(2)
Ex:
somaLista [1, 2, 3, 4, 5]
= 1 + somaLista [2, 3, 4, 5]
(2)
(2)
(2)
= 1 + (2 + ( 3 + ( 4 + somaLista [5])))
(2)
= 1 + (2 + ( 3 + ( 4 + ( 5 + somaLista []))))
(2)
= 1 + (2 + ( 3 + ( 4 + ( 5 + 0))))
(1)
= 15
(+)
Uma funo que teria uma definio muito parecida com a definio de somaLista,
seria a funo para determinar a lista cujos elementos so o dobro dos elementos de uma
lista:
21
= []
dobraLista (a:x)
= 2*a : dobraLista x
length []
=0
length (a:x)
= 1 + length x
A lista vazia tem tamanho 0. A lista no vazia, possui sempre um elemento a mais
que o seu tail.
Esta definio serve para qualquer tipo de listas, tanto para nmeros quanto para
caracteres, etc, por isso usa-se a varivel de tipo t na declarao da funo.
22
ordenacao []
= []
ordenacao (a:x)
= insere a (ordenacao x)
insere e []
= [e]
Para se inserir um elemento no lugar certo em uma lista ordenada tem-se dois casos:
insere e (a:x)
| e <=a
= e:(a:x)
| otherwise
= a : insere e x
23
[ 2 * a | a < - list ]
[2, 14, 6]
ou
24
No exemplo a funo even devolve o valor booleano True se o seu argumento for
um nmero par. Ento esta list comprehention devolve apenas os valores pares da lista list.
Nos geradores pode-se trabalhar com qualquer tipo de pattern.
Ex:
Ex:
Ento:
Haskell > pares [1,2,3] [4,5]
[(1,4), (1,5), (2,4), (2,5), (3,4), (3,5)]
25
Na funo nomes, foi usada a funo pegaNome, que foi definida localmente
atravs da palavra reservada where. Esta definio no serve para nenhuma outra funo
no script. Ela s funciona na funo nomes.
A funo nomes poderia ter sido definida de uma maneira mais simples:
2.5 Definies
A maioria das definies sobre listas se encaixam em trs casos: folding, que a
colocao de um operador entre os elementos de uma lista, filtering, que significa filtrar
26
foldr1
A definio em Haskell :
foldr1 f [a]
=a
foldr1 f (a:b:x)
= f a (foldr1 f (b:x))
A funo tem como argumento um operador (ou melhor, uma funo com dois
argumentos), e uma lista. Ex:
Haskell > foldr1 (++) [Concatenar ,uma ,lista ,de ,strings ,em ,uma ,s.]
Concatenar uma lista de strings em uma s.
27
Existe a funo foldr que tem um argumento a mais, que seria o que deve devolver
como resposta caso seja passada uma lista vazia como argumento:
Ex:
map
A definio:
map f []
= []
map f (a:x)
= f a : map f x
Exemplo:
filter
filter p [] = []
filter p (a:x)
|pa
= a: filter p x
| otherwise
= filter p x
Exemplo:
filter p x = [ a | a <- x, p a]
29
Ento:
Haskell > alunos baseDeDados
[Andr]
A funo take n gera uma lista com os n primeiros elementos da lista parmetro:
take _ []
= []
take 0 _
= []
take n (a:x)
= a : take (n-1) x
30
A funo drop n gera uma lista sem os n primeiros elementos da lista parmetro,
sua definio parecida com a da funo take:
drop 0 list
drop _ []
drop n (a:x)
= list
= []
= drop (n-1) x
Exemplo:
Haskell > drop 3 [2, 4, 6, 8, 10]
[8, 10]
31
takeWhile p []
= []
takeWhile p (a:x)
|pa
= a: takeWhile p x
| otherwise
= []
= []
A lista gerada pela funo zip sempre ter o mesmo nmero de elementos da menor
lista passada como argumento. Existe uma funo pr-definida da linguagem derivada da
funo zip, a funo zipWith:
32
f (x) = 7
e passamos o seguinte argumento:
f((21 + 33) * 8) = 7
uns = 1 : uns
33
= a+b
Temos:
A estrutura uns
iterate f x = [ x ] ++ iterate f (f x)
Esta funo constri uma seqncia em que o prximo elemento o valor gerado
aplicando-se uma funo ao elemento anterior. Ex:
Pode-se definir uma funo que pegue todos os valores at a posio n em uma
iterao.
34
Ento:
[3 .. ] = [3, 4, 5, 6 ...
Podese definir ento uma funo que ache todas as potncias de um nmero
inteiro:
Temse ento
2.8 Erros
Se for passado para a funo take um valor negativo, ela ira devolver uma
mensagem de erro:
35
que pra a avaliao de uma expresso caso ocorra um valor no desejado (). A definio
final da funo take seria:
take
take 0 _
= []
take _ []
= []
= x : take (n-1) xs
take _ _
36
3.1 Currying
soma x y
x+y
incrementa = soma 1
Ex:
Haskell > incremeta 4
5
37
soma
soma 2
soma 2 3
:: Int
Aplicando-se um argumento:
y. (x. x + y) 3
38
(+1)
(1+)
(<=100)
(Haskell ++) Funo que concatena a string Haskell no incio de outra string
(++ Haskell) Funo que concatena a string Haskell no final de uma string
Tabela 7. Operator Sections
(op x) y
= y op x
(x op) y
= x op y
soma = (+)
39
Ento:
Haskell > removePontuacao Haskell. muito bom, para manipular strings !!!
Haskell muito bom para manipular strings
f (g x) = (f . g) x
e seu tipo
40
Ao invs de usar equaes para definir funes, pode-se utilizar uma notao
lambda, em que a funo no precisa ter um nome. Por exemplo a funo
sucessor x = x+1
\x -> x + 1
Da mesma maneira a funo soma poderia ter sido definida da seguinte maneira:
soma = \ x y -> x + y
41
(.)
f.g
= \x -> f (g x)
42
ou seja, ele uma funo polimrfica. Porm este polimorfismo diferente do da funo
length. Analisando-se a definio da funo length, observa-se que a mesma definio
vale para qualquer tipo de listas:
length []
=0
length (a:x)
= 1 + length x
J o operador (==) tem uma definio diferente para cada tipo, pois no o mesmo
algoritmo que calcula a igualdade entre listas, caracteres ou nmeros. Este operador
tambm no funciona para todos os tipos, por exemplo, no existe um algoritmo que diga
se uma funo igual a outra.
Em Haskell chama-se classe o conjunto de tipos sobre os quais uma funo
definida. Por exemplo a equality class, ou classe Eq, o conjunto de tipos em que o
operador (==) definido.
A classe Eq definida da seguinte maneira:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y
= not (x==y)
43
= (x==a) && (y == b)
iguala _ _
= False
Exemplo:
Haskell > iguala (Rua "Abobora" (Apto 13 403)) (Rua "Abobora" (Apto 13 403))
True
44
Haskell > (Rua "Abobora" (Apto 13 403)) == (Rua "Abobora" (Apto 13 403))
True
Tambm pode-se usar o operador (/=), pois na classe ele definido como:
x /= y
= not (x==y)
Ento:
Haskell > (Rua "Azul" (Apto 1 403)) /= (Rua "Marrom" (Casa 10))
True
4.2 Classes Derivadas
Uma classe pode ser derivada de outra. Dessa maneira alm de ter as suas operaes
prprias, possui tambm as operaes da super-classe. Um exemplo de classe derivada a
classe Ord. Ela definida de uma maneira similar:
max, min
:: a -> a -> a
45
Para um tipo pertencer a esta classe, ele tambm tem que pertencer a classe Eq.
Pode-se dizer tambm que a classe Ord herda as operaes da classe Eq, o que tornaria a
idia mais parecida com a da orientao a objetos.
Haskell tambm permite heranas mltiplas, pois uma classe pode ter mais de uma
super-classe:
4.3 Contexto
elem x []
= False
Como foi visto at agora, o tipo desta funo poderia ser polimrfico:
Esta definio pode ser lida como Para cada tipo a que pertencer a classe Eq, a
funo elem tem tipo a -> [a] -> Bool.
46
Alm das classes Ord e Eq citadas anteriormente existem vrias outras classes prdefinidas em Haskell. Aqui sero mostradas algumas das mais importantes:
4.4.1 Enum
a classe dos tipos que podem ser enumerados, podendo ento gerar listas como
:: a -> [a]
-- [n..]
enumFromThen
-- [n,m..]
enumFromTo
-- [n..m]
enumFromThenTo
47
Os tipos instanciados na classe Show, so todos os tipos que podem ser convertidos
para listas de caracteres (strings). A classe Read fornece operaes para transformar
strings em valores de algum tipo.
As principais funes so:
show :: (Show t)
read :: (Read t)
:: a -> a -> a
negate
:: a -> a
abs, signum
:: a -> a
fromInteger
:: Integer -> a
fromInt
:: Int -> a
48
49
data Meses = Jan | Fev | Mar | Abr | Mai | Jun | Jul | Ago | Set | Out | Nov | Dez
Este tipo um enumerated type. Ele formado por doze valores que so chamados
de construtores (constructors) de tipo. Uma definio de tipo comea sempre com a palavra
data, depois vem o nome do tipo (Meses), que deve comear com letra maiscula (note
que todos os tipos em Haskell comeam com letra maiscula), e seus construtores (que
tambm comeam com letra maiscula).
Os construtores so todos os valores que um tipo pode assumir.
Um exemplo de tipo algbrico j conhecido o tipo Bool:
As funes que manipulam os tipos algbricos podem ser definidas por pattern
matching:
50
Exemplo:
Um tipo pode trabalhar com valores bem diferentes. Supondo que se queira
trabalhar com figuras geomtricas. O tipo pode assumir o valor de um crculo ou de um
retngulo. Ento:
O valor para o crculo poderia ser o raio, e para o retngulo poderia ser base e
altura.
Para se definir uma funo que calcula a rea de um objeto do tipo Forma pode-se
trabalhar novamente com pattern matching:
area (Circulo r)
= pi * r * r
area (Retangulo b a)
=b*a
Outro exemplo do mesmo princpio seria para se trabalhar com endereos. Algumas
ruas tem nomes e outras so representadas por nmeros. Ex:
51
Agora pode-se definir operaes que formatam o endereo usando pattern matching
em cima dos construtores.
data Meses = Jan | Fev | Mar | Abr | Mai | Jun | Jul | Ago | Set | Out | Nov | Dez
deriving (Eq, Show, Enum)
52
Uma rvore pode ser um valor nulo ou um node que composto por um valor
inteiro e duas sub-rvores.
Ex:
Node 22 Null Null
22
12
15
16
1
Pode-se fazer definies recursivas em cima de rvores, como por exemplo uma
funo que some todos os elementos:
somaArvore Null
=0
53
Uma funo que segue o mesmo princpio a funo ocorrencia que diz quantas
vezes um valor aparece na rvore:
=0
| otherwise
54
Um par seria
:: Pares [Int]
:: Pares Bool
(...)
A definio anterior dada para rvores trabalhava com nmeros inteiros nos nodes.
Pode-se modificar a definio para que a rvore contenha qualquer tipo de valor nos nodes.
Ento o tipo rvore seria:
55
56
base1 :: Base
base1 = [ (1, Guarana, 0.70), (2, Cerveja Bacana lata, 0.50), (3, Usque Do
Bom, 22.0) ......]
Se a base estiver ordenada pelo cdigo do produto, fica muito mais fcil de se
implementar as funes, pois todas fazem algum tipo de procura em cima da base. O nico
57
type
Conjunto t = [t]
in
vazio
:: Conjunto t,
unitario
:: t -> Conjunto t,
membroConj
uniao
inter
dif
58
subConj
leqConj
constConj
mapConj
filterConj
foldConj
mostra
card
conjUniao
conjInter
vazio = []
unitario a = [a]
A funo membroConj devolve um valor booleano que diz se o elemento passado
como parmetro est ou no no conjunto. Esta definio recursiva, e utiliza a
caracterstica do conjunto ter seus elementos em ordem:
membroConj [] a = False
membroConj (a:x) b
| a<b
= membroConj x b
| a == b
= True
| otherwise
= False
59
uniao [] a
=a
uniao a []
=a
= a : uniao x (b:y)
| a == b
= a : uniao x y
| otherwise
= b : uniao (a:x) y
inter [] a
= []
inter a []
= []
= inter x (b:y)
| a == b
= a : inter x y
| otherwise
= inter (a:x) y
dif [] a = []
dif a [] = a
dif (a:x) (b:y)
| a == b
= dif x y
|a<b
= a : dif x (b:y)
| otherwise
= dif (a:x) y
A subConj (devolve um valor booleano dizendo se um conjunto ou no subconjunto de outro) definida como as outras por pattern matching tendo trs casos:
60
subConj [] a = True
subConj x [] = False
subConj (a:x) (b:y)
| a<b
= False
| a == b
= subConj x y
| a>b
= subConj (a:x) y
sort []
= []
sort (a:x)
= ins a (sort x)
ins a [] = [a]
ins a (b:y)
| a <= b
= a : (b:y)
| otherwise
= b : ins a y
61
eliminaRep [] = []
eliminaRep [a]
= [a]
eliminaRep (a:b:x)
| a == b
= eliminaRep (b:x)
| otherwise
= a : eliminaRep (b:x)
Exemplos:
Haskell > uniao (constConj [4, 3, 1, 22, 4]) (constConj [4, 34, 1, 3])
[1, 3, 4, 22, 34]
Haskell > inter (uniao (constConj [1,2,3]) (constConj [2,3,4,5])) (constConj [3,4,5])
[3, 4, 5]
conjIgual = (==)
leqConj = (<=)
filterConj = filter
62
card = length
Na verso de map para conjuntos deve-se cuidar os elementos repetidos que podem
aparecer:
Para se poder trabalhar com os conjuntos, eles devem estar instanciados na classe
show. Um conjunto pode ser exibido na tela da mesma maneira que uma lista. Por isso se
usa a funo showList.
mostra = showList
63
Existem vrias outras definies que podem ser feitas sobre conjuntos. Para isso
basta acrescentar a type signature da funo na lista de funes e depois a sua definio.
Segue agora o script completo do tipo conjunto:
-- script de conjuntos
type
Conjunto t = [t]
in
vazio
:: Conjunto t,
unitario
:: t -> Conjunto t,
membroConj
uniao
inter
dif
conjIgual
subConj
leqConj
constConj
mapConj
filterConj
foldConj
mostra
card
conjUniao
64
vazio = []
unitario a = [a]
membroConj [] a = False
membroConj (a:x) b
| a<b
= membroConj x b
| a == b
= True
| otherwise = False
uniao [] a
=a
uniao a []
=a
= a : uniao x (b:y)
| a == b
= a : uniao x y
inter [] a
= []
inter a []
= []
= inter x (b:y)
| a == b
= a : inter x y
dif [] a = []
dif a [] = a
dif (a:x) (b:y)
| a == b
= dif x y
|a<b
= a : dif x (b:y)
65
conjIgual = (==)
subConj [] a = True
subConj x [] = False
subConj (a:x) (b:y)
| a<b
= False
| a == b
= subConj x y
| a>b
= subConj (a:x) y
leqConj = (<=)
= []
sort (a:x)
= ins a (sort x)
= a : (b:y)
| otherwise = b : ins a y
= [a]
eliminaRep (a:b:x)
| a == b
= eliminaRep (b:x)
66
mostra = showList
filterConj = filter
foldConj = foldr
card = length
67
CAPTULO 7 IO
sendo que
Se o valor devolvido por uma funo for do tipo IO, o interpretador Haskell no
responde simplesmente imprimindo o valor na tela, e sim mandando uma requisio ao
sistema operacional para que faa a entrada ou sada de dados. Ex:
getChar :: IO Char
sabe-se que ela realiza uma ao e retorna um caracter. Quando uma funo no
retorna nada de til utiliza-se o tipo ( ). Por exemplo, a funo
68
tem como argumento um caracter, e no devolve nenhum valor. o mesmo caso da funo
putStr.
Uma seqncia de entrada e sada de dados expressa atravs de uma expresso do.
Segue um exemplo de programa simples utilizando o do.
main = do
putStr (Escreva uma palavra: )
palavra <- getLine
putStr (Palavra invertida: ++ reverse palavra)
A funo getLine faz com que o sistema operacional leia uma linha, e associe esta
seqncia de caracteres varivel a esquerda da flecha (<-), ou seja palavra. Esta varivel
s pode ser acessada dentro da expresso do. Por isso a funo tem tipo:
getLine :: IO String.
Haskell >
main :: IO ()
69
pois ela no devolve nenhum valor, simplesmente realiza uma srie de aes de entrada e
sada.
7.2 Arquivos
main = do
putStr ("Escreva uma linha e tecle ENTER: ")
linha <- getLine
nome <- criaArq linha
putStr ("A linha \n" ++ linha ++ "\nesta no arquivo " ++ nome ++ "!")
70
return :: a -> IO a.
Haskell >
Pode-se fazer uma funo que crie o arquivo Haskell2.txt com o contedo de
Haskell.txt mais uma linha digitada pelo usurio:
adiciona = do
putStr ("Escreva uma linha para adicionar ao arquivo Haskell2.txt:\n")
linha <- getLine
arquivo <- readFile "Haskell.txt"
writeFile "Haskell2.txt" (arquivo ++ "\n" ++ linha)
putStr ("Linha adicionada!")
A funo readFile associa Haskell.txt a varivel arquivo, isso feito by-need, ou
seja o contedo s lido quando necessrio, seguindo a estratgia da lazy evaluation.
71
main = do
nomes <- leNomes
putStr (unlines (sort nomes))
leNomes = do
putStr ("Escreva um nome: ")
nome <- getLine
if nome == ""
then return []
else do
nomes <- leNomes
return ([nome] ++ nomes)
sort [] = []
sort (a:b)
72
que recebe uma lista de strings, e a transforma em uma string colocando o caracter de nova
linha (\n) entre os elementos. Um exemplo do uso da funo seria:
Haskell >
7.4 Mnadas
73
7.1 Mdulos
push x (Stack y)
= Stack (x:y)
=a
pilhaVazia :: Pilha t
pilhaVazia = Stack []
74
Esta implementao de pilha pode ser reutilizada por outros programas em Haskell.
Para isso necessrio criar um mdulo. O mdulo Pilha seria construdo da seguinte
maneira:
import Pilha.
75
Para tornar o tipo pilha um ADT, basta no incluir na lista de funes pblicas o
construtor do tipo:
Pode-se ento criar uma funo que transforme uma lista em pilha, no mdulo pilha:
ento:
76