Haskell/Entradas e saídas simples: diferenças entre revisões
[edição não verificada] | [edição não verificada] |
Conteúdo apagado Conteúdo adicionado
m peq. correção |
m <source> -> <syntaxhighlight> (phab:T237267) |
||
Linha 64:
Vale notar que há duas formas de se escrever explicitamente o tipo da saída de <code>read</code>:
<
-- O tipo de 'a' é definido a partir da expressão de dentro (a partir de 'read'):
a = (read "1" :: Float)
Linha 71:
b :: Float
b = read "2"
</syntaxhighlight>
A função <code>show</code> (''show'' em inglês significa "mostrar") é exatamente o oposto de <code>read</code>: ela converte um dado para uma representação em texto. Seu tipo é:
Linha 109:
É exatamente isso que a notação <code>do</code> faz: nos permite criar sequências de ações dentro de uma função <code>IO</code>. Veja:
<
main :: IO ()
main = do
Linha 115:
nome <- getLine
putStrLn ("Olá, " ++ nome ++ ". Como vai?")
</syntaxhighlight>
{{Nota|Poderíamos explicar a fundo a notação ''do'', mas alguns outros tópicos já devem ser de nosso conhecimento para entendermos seu funcionamento. Por hora, nos basta saber usá-la, pois ela nos permite criar programas completos, com ações externas. Não é recomendável, mas caso você quera se arriscar a entender ''do'', a explicação está contida no capítulo [[Haskell/Entendendo mônadas|Entendendo mônadas]] em diante.}}
Linha 139:
Mesmo que sejam criadas variáveis dentro de um programa, nem sempre somos obrigados a usá-las. Além do mais, dentro de uma função <code>IO</code>, <code><-</code> pode ser usada em qualquer ação, exceto a última.
# Um caso em que não criamos variável e, portanto, não usamos o resultado de <code>getLine</code>, apesar deste comando ser executado mesmo assim:<
main = do
putStrLn "Digite seu nome:"
getLine
putStrLn "Como vai?"
</syntaxhighlight>
# Um caso em que criamos duas variáveis, mas ambas não são usadas:<
main = do
x <- putStrLn "Digite seu nome:"
nome <- getLine
putStrLn "Olá. Como vai?"
</syntaxhighlight>
# Um caso em que a última ação é uma associação usando <code><-</code> e, portanto, é inválido:<
main = do
x <- putStrLn "Digite seu nome:"
nome <- getLine
y <- putStrLn ("Olá, " ++ nome ++ ". Como vai?")
</syntaxhighlight>
No exemplo 3, teríamos um erro do compilador:
Linha 167:
Outra função de <code><-</code> é extrair o dado de tipo <code>a</code> de dentro de <code>IO a</code>. Veja a seguinte linha:
<
nome <- getLine
</syntaxhighlight>
Se pudéssemos usar <tt>:t</tt> para descobrir tipo de <code>nome</code>, ele seria <code>String.</code>. Como já sabemos, <code>getLine</code> é uma função sem argumentos que retorna um dado do tipo <code>IO String</code>. Ao associar seu resultado a uma variável usando <code><-</code>, o valor do tipo <code>String</code> é extraído de dentro de <code>IO String</code>. Assim, ele pode ser usado com um <code>String</code> normal. Abra o GHCi e teste por você mesmo:
Linha 196:
Vejamos um simples programa de "advinho o número":
<
adivinhe num = do
putStrLn "Digite um número:"
Linha 207:
putStrLn "Tente novamente!"
else putStrLn "Você acertou!"
</syntaxhighlight>
No caso da função <code>adivinhe</code>, temos:
Linha 231:
Não tem simplifica seu programa eliminando variáveis. Já vimos um exemplo similar:
<
main = do putStrLn "Qual o seu nome?"
putStrLn ("Olá, " ++ getLine)
</syntaxhighlight>
Temos um erro de tipo, pois <code>getLine</code> retorna um dado cujo tipo é <code>IO String</code>. Devemos, portanto, usar <code><-</code> para extrair o <code>String</code>:
<
main = do putStrLn "Qual o seu nome?"
nome <- getLine
putStrLn ("Olá, " ++ nome)
</syntaxhighlight>
=== Atenção quanto aos tipos das associações ===
Linha 248:
Devemos ter cuidado ao criar variáveis dentro de blocos <code>do</code>, pois <code><-</code> só funciona para extrair dados. Caso o valor já seja um dado puro, não podemos associá-lo a uma variável. O exemplo a seguir resulta num erro:
<
main = do putStrLn "Digite um número inteiro:"
texto <- getLine
numero <- (read texto :: Int)
putStrLn ("O dobro do seu número é: " ++ (show (2 * numero)))
</syntaxhighlight>
Vamos interpretar o programa:
# Extraímos o <code>String</code> de dentro de <code>IO String</code>, que é o resultado de <code>getLine</code>, usando <code><-</code>.
Linha 263:
Uma possível solução seria usar <code>where</code> para definir uma função interna:
<
main = do putStrLn "Digite um número: "
texto <- getLine
putStrLn ("O dobro do seu número é: " ++ (show . dobrar) texto)
where dobrar x = 2 * (read x :: Int)
</syntaxhighlight>
Outra solução é usar <code>let</code>:
Linha 276:
|-
||
<
main = do putStrLn "Digite um número: "
texto <- getLine
let dobro = 2 * (read texto :: Int)
putStrLn ("O dobro do seu número é: " ++ (show dobro))
</syntaxhighlight>
||
<
main = do putStrLn "Digite um número: "
texto <- getLine
let dobro = 2 * (read texto :: Int) in
do putStrLn ("O dobro do seu número é: " ++ (show dobro))
</syntaxhighlight>
|}
As duas opção são válidas, pois dentro de um bloco <code>do</code> temos a opção de usar ou não <code>in</code>.
|