Jump to content

IO haskell ajuda


crislanio_macedo
 Share

Recommended Posts

Fatorial com IO:

Olá a todos, o código abaixo dá o seguinte erro.

Como eu faria esse programa, usando ao invês de print (fat ( read numero)) algo como

import Control.Monad

fat a | a==0 =0
   | a==1 =1
   | otherwise = a*fat(a-1)
main = do
   putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
   numero <- getLine
   putStrLn ("O Fatorial de " ++ numero ++ " é " ++ fat ( read numero))
   -- print (fat ( read numero))

Pois assim dá o seguinte erro:

3$ ghc --make ioTESTE.hs
[1 of 1] Compiling Main ( ioTESTE.hs, ioTESTE.o )

ioTESTE.hs:38:51:
No instance for (Num [Char]) arising from a use of `fat'
Possible fix: add an instance declaration for (Num [Char])
In the second argument of `(++)', namely `fat (read numero)'
In the second argument of `(++)', namely
`" \233 " ++ fat (read numero)'
In the second argument of `(++)', namely
`numero ++ " \233 " ++ fat (read numero)'

3$ ghc --make 10-fatorialIO.hs
[1 of 1] Compiling Main ( 10-fatorialIO.hs, 10-fatorialIO.o )

10-fatorialIO.hs:17:17: parse error on input `main'

import Control.Monad

fat a | a==0 =0
   | a==1 =1
   | otherwise = a*fat(a-1)

main = do
   putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
   numero <- getLine
   when (numero /= 0) $ do
    if fat numero
	    then do
	    putStrLn ("O Fatorial de " ++ numero ++ " é ")
	    print (fat ( read numero))
	    main
    else do
	    putStrLn ("O Fatorial de " ++ numero ++ " é ")
	    print (fat ( read numero))
	    main
Edited by crislanio_macedo
Link to comment
Share on other sites

crislanio_macedo,

Todos os teus excertos de código estão mal indentados, o que significa que se alguém quiser copiar e colar para os testar, terá que indentar manualmente -- deves corrigir isso.

Relativamente ao teu problema, qual é a assinatura da função fat?

*Main> :type fat
fat :: (Eq a, Num a) => a -> a

E qual é a assinatura do operador ++?

*Main> :type (++)
(++) :: [a] -> [a] -> [a]

E para terminar, qual é a assinatura de putStrLn?

*Main> :type putStrLn
putStrLn :: String -> IO ()

Vamos então juntar as peças.

A função putStrLn mostra uma String no ecrã. Tu estás a construir essa String (que na realidade é uma [Char]) com o operador ++. Tendo em conta a assinatura deste operador, percebe-se facilmente que só podes utilizá-lo para unir listas com o mesmo tipo de dados, ou seja, não podes fazer algo como "a" ++ [1].

E chegamos finalmente ao teu problema: uma vez que fat devolve um número (como indicado pelo Num a na sua assinatura) e estás a tentar unir um número com o resto da String que queres mostrar no ecrã, obténs um erro.

A solução é transformar o resultado da fat numa String também, utilizando a função show.

PS.: Isto diz respeito ao primeiro excerto de código. Não vi o outro por estar incorrectamente indentado; quando o corrigires poderemos discutir os problemas que tenhas nele também.

Link to comment
Share on other sites

Ainda não percebeste o problema.

putStrLn ("O Fatorial de " ++ numero ++ " é ")

Esse código não compila porque numero é de um tipo de dados diferente de String.

Volto a exemplificar:

"isto" ++ "aquilo"   -- ok: "istoaquilo"
"isto" ++ (show 42)  -- ok: "isto42"
"isto" ++ 42         -- erro. '42' é um Integer e não uma String (ou [Char])
Link to comment
Share on other sites

putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
numero <- getLine
putStrLn ("O Fatorial de " ++ (show numero) ++ " é ")
putStrLn (show (fat (read numero)) )

Ok deu certo.

No caso como eu faria para que ao digitar 0 realmente parar o programa,

main = do
   putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
   numero <- getLine
   when (show(numero) /= "0") $ do
    putStrLn ("O Fatorial de " ++ (show numero) ++ " é ")
    putStrLn (show (fat (read numero)) )
    main

Pois não está a fazer essa operação

Link to comment
Share on other sites

Tens um problema complicado aí. Vou comentar directamente no código:

main = do
   putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
   numero <- getLine  -- 'numero' é do tipo String.

   -- se 'numero' fosse um Integer, então 'show numero' seria "0" (uma string que contém 0)
   -- no entanto, 'numero' é uma String, por isso 'show numero' é na realidade "\"0\"" (uma string que contém "0")
   -- por esse motivo, a condição 'show(numero) /= "0"' nunca irá ser verdadeira, e o teu programa nunca terminará.
   when (show(numero) /= "0") $ do
       putStrLn ("O Fatorial de " ++ (show numero) ++ " é ")
       putStrLn (show (fat (read numero)) )
       main

No entanto, o teu código podia estar muito mais limpo. Continuas com problemas no que diz respeito à utilização de parênteses. Além disso, numero não devia ser uma String. Aqui fica uma versão mais limpa:

main = do
 putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
 numero <- readLn
 when (numero /= 0) $ do
   putStrLn $ "O Fatorial de " ++ (show numero) ++ " é "
   putStrLn $ show (fat numero)
   main
  • Vote 1
Link to comment
Share on other sites

Tens um problema complicado aí. Vou comentar directamente no código:

main = do
putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
numero <- getLine  -- 'numero' é do tipo String.

-- se 'numero' fosse um Integer, então 'show numero' seria "0" (uma string que contém 0)
-- no entanto, 'numero' é uma String, por isso 'show numero' é na realidade "\"0\"" (uma string que contém "0")
-- por esse motivo, a condição 'show(numero) /= "0"' nunca irá ser verdadeira, e o teu programa nunca terminará.
when (show(numero) /= "0") $ do
	putStrLn ("O Fatorial de " ++ (show numero) ++ " é ")
	putStrLn (show (fat (read numero)) )
	main

No entanto, o teu código podia estar muito mais limpo. Continuas com problemas no que diz respeito à utilização de parênteses. Além disso, numero não devia ser uma String. Aqui fica uma versão mais limpa:

main = do
 putStrLn "Informe um para saber o saber o seu fatorial, ou escreva sair para sair"
 numero <- readLn
 when (numero /= 0) $ do
putStrLn $ "O Fatorial de " ++ (show numero) ++ " é "
putStrLn $ show (fat numero)
main

Realmente bem mais limpo, Obrigado pela ajuda !!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.