Ir para o conteúdo
leslie

Dúvida de como definir o tipo da variável e criar um for

Mensagens Recomendadas

leslie

Bom dia! Eu baixei no site http://www.haskell.org/platform/ a plataforma do Haskell,

que o mesmo instala GHCi, eu tentei seguir alguns tutorial encontrados na web como

abrir um arquivo .hs pelo comando :load funcao.hs, mas ocorre erro sendo que neste arquivo

tem algo do tipo:

idade :: Int
idade = 17

maiorDeIdade :: Bool -- Usa a definição de idade
maiorDeIdade = (idade>=18)

Na primeira linha já retorna um erro no tipo: Not in scope: 'idade'

Também tentei executar a função de exemplo clássico usando recursividade

com fatorial, mas também não obtive sucesso, como:

fatorial :: Integer -> Integer
fatorial 0 = 1
fatorial n = n * fatorial(n-1)

ou

factorial :: (Num a) => a -> a
factorial 0 = 1
factorial n = n * factorial (n - 1) 

Fico aguardando se alguem pode me ajudar nesta questão. Além disso se poder

mostrar uma breve recurssão de como fazer um for ou do while em haskell,

pois ainda estou com problemas nisso também

att.

Lesliê Cardoso

Editado por thoga31
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

leslie,

Não existe problema nenhum com o fragmento de código que colocaste em cima. Certamente estás a fazer algo mal na invocação do mesmo ou a utilizar mal os programas necessários.

Descreve com maior detalhe o que estás a fazer. Se estás a introduzir o código directamente no (Win)GHCi, então esse é o problema. O código deve ser guardado num ficheiro e carregado a partir dele para o interpretador (GHCi).

Relativamente à tua questão sobre ciclos (for e while) em Haskell não existe mutabilidade de variáveis, e portanto não pode existir um contador ou uma variável que se altera à medida que o ciclo progride. Por este motivo, em Haskell não existem ciclos, mas podemos simulá-los com funções recursivas, como a função factorial que tu mesmo mostraste no teu post.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
leslie

leslie,

Não existe problema nenhum com o fragmento de código que colocaste em cima. Certamente estás a fazer algo mal na invocação do mesmo ou a utilizar mal os programas necessários.

Descreve com maior detalhe o que estás a fazer. Se estás a introduzir o código directamente no (Win)GHCi, então esse é o problema. O código deve ser guardado num ficheiro e carregado a partir dele para o interpretador (GHCi).

Relativamente à tua questão sobre ciclos (for e while) em Haskell não existe mutabilidade de variáveis, e portanto não pode existir um contador ou uma variável que se altera à medida que o ciclo progride. Por este motivo, em Haskell não existem ciclos, mas podemos simulá-los com funções recursivas, como a função factorial que tu mesmo mostraste no teu post.

O código correto de carregar o arquivo é esse: :load funcao.hs. Eu clicando no arquivo percebi que tirando esse código realmente funcionou:

mini :: Int -> Int -> Int -- função que mostra o menor valor entre dois inteiros
mini a b
| a <= b = a
| otherwise = b

Pois nele está ocorrendo o seguinte erro: parse error on input '|'

Lendo sobre Haskell antes de postar essas dúvidas já tinha visto que não existe laços de repetição, então só queria saber como simularia isso usando uma função recursiva para imprimir uma sequência de números 1 a 100 por exemplo, para entender melhor como faria o mesmo.

Por fim, somente o seguinte código:

factorial :: (Num a) => a -> a
factorial 0 = 1
factorial n = n * factorial (n - 1)

Em um arquivo factorial.hs não executa

Editado por thoga31
GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Quando utilizas pattern guards tens que indentar o código correctamente (Haskell é sensível à indentação):

mini :: Int -> Int -> Int
mini a b
 | a <= b    = a
 | otherwise = b

Também podia ser assim:

mini :: Int -> Int -> Int
mini a b | a <= b    = a
        | otherwise = b

Relativamente à questão do ciclo, aqui fica um exemplo. Este exemplo é ligeiramente complexo porque estamos a lidar com algo que em Haskell não é tão simples como noutras linguagens: output.

Mas essencialmente, a função ciclo aceita dois argumentos (Int -> Int) e executa acções de input/output sem devolver nada (-> IO ()). Dentro da função ciclo, comparamos i com f e caso sejam diferentes, imprimimos o valor de i e chamamos recursivamente a função ciclo passando-lhe um valor de i incrementado por 1.

Quando i for igual a f, chegámos ao final do nosso "ciclo".

Aqui fica o código:

main :: IO ()
main = ciclo 1 100

ciclo :: Int -> Int -> IO ()
ciclo i f = do
 print i
 if i == f then return ()
           else ciclo (i + 1) f

Uma forma mais simples seria simplesmente gerar uma lista com n elementos:

genList :: Int -> Int -> [int]
genList i f | i == f    = [i]
           | otherwise = i : genList (i + 1) f

e depois podes fazer o seguinte no GHCi:

GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main         ( leslie.hs, interpreted )
Ok, modules loaded: Main.
*Main> genList 1 20
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

EDIT: devo lembrar que Haskell já tem funções disponíveis para gerar listas deste género, e tem até uma notação específica para tal:

*Main> [1..10]
[1,2,3,4,5,6,7,8,9,10]

E já agora, devo adicionar que até mesmo para a operação que descrevi (de imprimir os números no ecrã), poderíamos simplificá-la a algo como:

main :: IO ()
main = mapM_ print [1..100]

Fica para quando te sentires mais à vontade na linguagem e te aperceberes que há mecanismos mais abstractos que os ciclos para realizar repetições em Haskell :)

Editado por pwseo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
leslie

Quando utilizas pattern guards tens que indentar o código correctamente (Haskell é sensível à indentação):

mini :: Int -> Int -> Int
mini a b
 | a <= b	= a
 | otherwise = b

Também podia ser assim:

mini :: Int -> Int -> Int
mini a b | a <= b	= a
	 | otherwise = b

Relativamente à questão do ciclo, aqui fica um exemplo. Este exemplo é ligeiramente complexo porque estamos a lidar com algo que em Haskell não é tão simples como noutras linguagens: output.

Mas essencialmente, a função ciclo aceita dois argumentos (Int -> Int) e executa acções de input/output sem devolver nada (-> IO ()). Dentro da função ciclo, comparamos i com f e caso sejam diferentes, imprimimos o valor de i e chamamos recursivamente a função ciclo passando-lhe um valor de i incrementado por 1.

Quando i for igual a f, chegámos ao final do nosso "ciclo".

Aqui fica o código:

main :: IO ()
main = ciclo 1 100

ciclo :: Int -> Int -> IO ()
ciclo i f = do
 print i
 if i == f then return ()
		else ciclo (i + 1) f

Uma forma mais simples seria simplesmente gerar uma lista com n elementos:

genList :: Int -> Int -> [int]
genList i f | i == f	= [i]
		| otherwise = i : genList (i + 1) f

e depois podes fazer o seguinte no GHCi:

GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( leslie.hs, interpreted )
Ok, modules loaded: Main.
*Main> genList 1 20
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

EDIT: devo lembrar que Haskell já tem funções disponíveis para gerar listas deste género, e tem até uma notação específica para tal:

*Main> [1..10]
[1,2,3,4,5,6,7,8,9,10]

E já agora, devo adicionar que até mesmo para a operação que descrevi (de imprimir os números no ecrã), poderíamos simplificá-la a algo como:

main :: IO ()
main = mapM_ print [1..100]

Fica para quando te sentires mais à vontade na linguagem e te aperceberes que há mecanismos mais abstractos que os ciclos para realizar repetições em Haskell :)

Muito obrigado pela paciência e excelente explicação exemplificada :)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.