Guest id194 Posted December 26, 2006 at 02:27 AM Report #72407 Posted December 26, 2006 at 02:27 AM Estou aqui com um poroblema gravissimo que me esta a impedir a continução deste trabalho para entregar até dia 2 e ainda vou no inicio... Num determinado exercicio tinhamos de gerar numeros aleatorios e para isso, com uma pesquisa na net, desenvolvi o seguinte código: -- Gera um número aleatório compreendido entre o par (x, y) geraNumeroAleatorio :: (Int, Int) -> IO Int geraNumeroAleatorio (x, y) = do r <- getStdRandom $ randomR (x, y) return r O problema esta em usar o valor devolvido por esta função para outros fins onde apenas tenho de usar Int e não IO Int. Por exemplo, criar uma lista de inteiros com vários numeros aleatorios e depois somar todos esses valores excluindo o mais baixo. Tudo isto era muito fácil se fosse uma lista de Int, numa lista de IO Int não consigo, mas eu preferia saber (se possível) como converter o valor devolvido pela função geraNumeroAleatorio do tipo IO Int para apenas Int.
Rui Carlos Posted December 26, 2006 at 11:13 AM Report #72417 Posted December 26, 2006 at 11:13 AM não sei se isso será possível... penso que só podes usar funções do tipo IO dentro de outras funções do tipo IO. deixo-te aqui uma função semelhante à que tens mas que te calcula uma lista de n números aleatórios, talvez ajude... geraN::Int->(Int,Int)->IO [int] geraN 0 _ =return [] geraN n (x,y)=do l<-geraN (n-1) (x,y) new<-randomRIO (x,y) return (new:l) Rui Carlos Gonçalves
Guest id194 Posted December 26, 2006 at 02:43 PM Report #72462 Posted December 26, 2006 at 02:43 PM Que cena, se isso não dá pa fazer, cheira-me que nem um 1/4 do trabalho vou fazer... Porque tipo, tens essa lista de IO [int], imagina, com 4 valores: [2, 3, 4, 5]. Agora, o objectivo é, usar essa lista, remover o 2 (número mais baixo) e somar os restantes, o resultado seria 12. Como faço eu isso? Ou seja, nesta situações, de usar sempre IO Int, não vou puder usar a função sum, vou ter de criar a minha função sumIO, certo? Isto vai acontecer o mesmo para todas as outras funções que eu pretenda usar que já estejam definidas no haskell, não vou puder usar porque não funcionam com IO Int.
Rui Carlos Posted December 26, 2006 at 03:29 PM Report #72475 Posted December 26, 2006 at 03:29 PM podes fazer tudo o que fazia se não fosse com IO, só dá um pouco mais de trabalho... f::IO Int f=do l<-geraN 4 (1,10) let l1=removeMenor l let soma=sum l1 return soma esta função gera 4 números entre 1 e 10 aleatoriamente, remove o menor (através da função não monádica removaMenor, que terás de definir), soma os restantes valores e devolve essa soma. o operador '<-' permite-te ir buscar o resultado de uma função monádica. o operador 'let ... =' é usado com as não monádicas. Rui Carlos Gonçalves
Guest id194 Posted December 26, 2006 at 05:03 PM Report #72495 Posted December 26, 2006 at 05:03 PM Ok, acho que já tou a entrar na cena mas continuo com algumas questões: 1) Qual a diferença entre eu usar r <- getStdRandom $ randomR (x, y) e new<-randomRIO (x,y)? O caso azul é o que tu me disseste, o a vermelho foi o que eu vi na documentação oficial do Haskell. Qual a diferença e qual o modo recomendado? 2) Imagine-se o seguinte código: type ABC = IO (Int, Int, Int) geraABC :: ABC geraABC = do a <- 4 b <- 2 c <- 5 return (a, b, c) mostraABC :: ABC -> IO() mostraABC (x, y, z) = do putStrLn "A: " putStrLn (show x) putStrLn "B: " putStrLn (show y) putStrLn "C: " putStrLn (show z) O objectivo seria compilar correctamente, carregar o ficheiro e fazer o seguinte: abc <- geraABC mostraABC abc e apresentar os resultados no ecrã, mas isto não funciona porque dá o seguinte erro: Couldn't match `IO (Int, Int, Int)' against `(a, b, c)' Expected type: IO (Int, Int, Int) Inferred type: (a, b, c) When checking the pattern: (x, y, z) In the definition of `mostraABC': mostraABC (x, y, z) = do putStrLn "A: " putStrLn (show x) putStrLn "B: " putStrLn (show y) putStrLn "C: " putStrLn (show z) Tentei substituir o type inicial por: data ABC = IO (Int, Int, Int) | (Int, Int, Int) Mas dá erro a dizer que não é válido. O que me está escapar para ter este pequeno código a funcionar? (Claro que o verdadeiro exercicio não é este, isto é só um exemplo pequeno para ser mais fácil ajudarem-me).
Rui Carlos Posted December 26, 2006 at 05:43 PM Report #72498 Posted December 26, 2006 at 05:43 PM relativamente à primeira questão, eu fui à documentação do GHC e encontrei uma função que fazia o que era preciso (gerar números aleatórios) e usei essa função. a modo recomendado é aquele que tu entenderes melhor (ainda não entendi bem a tua solução, em principio e só ver a documentação que está no site, mas acho a minha solução mais simples). quanto à questão dois, (x,y,z) é uma coisa do tipo (a,b,c) e não IO (a,b,c). aliás, quando fizeres 'abc<-geraABC' vais ficar com uma variável do tipo (a,b,c). o efeito do operador '<-' é extrair o resultado de uma monad. podes fazer da seguinte forma: mostra::IO () mostra= do (x,y,z)<-geraABC putStrLn "A: " putStrLn (show x) ... deve resolver o problema. Rui Carlos Gonçalves
Guest id194 Posted December 26, 2006 at 05:57 PM Report #72504 Posted December 26, 2006 at 05:57 PM Isso não vai resolver bem o meu problema porque tipo: Na minha função geraABC, eu tenho valores fixos, mas era só um exemplo, estes valores irão ser aleatorios, logo eu quero puder fazer algo do genero: a <- geraABC b <- geraABC c <- geraABC (...) e depois chamo a função que mostra os valores do a, b ou c, conforme me apetecer, não quero gerar estes valores quando for chamar a função que irá mostrar os valores, logo tenho de passar como parametro na função "mostra" algo do tipo ABC. Ai é que esta o problema... por isso é que tentei a cena do Data, ter dois tipos de dados, mas não parece funcionar...
kAIOSHIN Posted December 27, 2006 at 07:28 PM Report #72759 Posted December 27, 2006 at 07:28 PM Boas! Bem...Parece-me que também estás a fazer o trabalho de P.F. 😁 Afinal sempre conseguiste transformar numa lista de inteiros? A funçao que o Rui Carlos fez que dá uma lista com n ºs aleatorios já chega para fazer os atributos do agente. Tipo, basta gerares uma lista com 4 números a variar entre 3 e 18 (o minimo e maximo de qualquer atributo) Mas gostava mesmo é de saber transformar numa lista de Inteiros, para depois poder usar os atributos na formula dos modificadores... :dontgetit:
Guest id194 Posted December 27, 2006 at 08:49 PM Report #72787 Posted December 27, 2006 at 08:49 PM sim, já resolvi os problemas todos que tinham criado neste tópico... A solução para o problema que mostrei no meio do topico pode passar pelo seguinte, porque eu tava a fazer uma confusão tremenda: type ABC = (Int, Int, Int) geraABC :: IO ABC geraABC = do a <- 4 b <- 2 c <- 5 return (a, b, c) mostraABC :: ABC -> IO() mostraABC (x, y, z) = do putStrLn "A: " putStrLn (show x) putStrLn "B: " putStrLn (show y) putStrLn "C: " putStrLn (show z) Compara os 2 e vê as diferenças, esta apenas nos IOs, não sei se isto te ajuda ou não porque não percebi bem a tua dúvida.
kAIOSHIN Posted December 28, 2006 at 06:11 PM Report #72976 Posted December 28, 2006 at 06:11 PM Bem, a minha dúvida é a seguinte. Nós temos lá a formula de modificação [(X-10)/2] certo? Preciso que os valores gerados anteriormente sejam Int, não?
[d-_-b] Posted December 29, 2006 at 12:16 AM Report #73138 Posted December 29, 2006 at 12:16 AM pessoal tb estou a fazer esse trabalho e ja terminei... so falta o relatorio em latex... vejam se isto ajuda: d6 = do getStdRandom (randomR (1,6)) geraCaract = do a <- d6; b <- d6; c <- d6; d <- d6; return (sum (tail (sort [a,b,c,d]))) ja agora... como passo esta ultima funcao tipo... sem parentises e com pontos? Abraço, Pires
Rui Carlos Posted December 29, 2006 at 10:58 AM Report #73184 Posted December 29, 2006 at 10:58 AM ' timestamp='1167351404' post='73138']ja agora... como passo esta ultima funcao tipo... sem parentises e com pontos? Abraço, Pires sum.tail.sort$[a,b,c,d] penso que isto deve funcionar... Rui Carlos Gonçalves
[d-_-b] Posted December 29, 2006 at 01:30 PM Report #73209 Posted December 29, 2006 at 01:30 PM obrigado amigo Rui Carlos... nao deu mas foi quase 😉 dp consegui chegar la: return $ (sum.tail.sort) [a,b,c,d] Abraço, Pires
kAIOSHIN Posted December 29, 2006 at 04:09 PM Report #73248 Posted December 29, 2006 at 04:09 PM Boas pessoal. Estou a ficar lixado... Acho que só me falta mesmo isto para conseguir fazer o resto do trabalho. Como é que conseguiram fazer, por exemplo a tarefa 6? A função recebe Int, mas os valores gerados aleatóriamente não sao Int. A função que o Pires fez ligeiramente modificada: d6 :: Int -> Int -> IO Int d6 x y = randomRIO (x,y) geraCaract = do a <- d6; b <- d6; c <- d6; d <- d6; return (a,b,c,d) Isto não devia de funcionar? Dar Inteiros? A mim dá-me este erro: *** Binding : geraCaract *** Outstanding context : Monad ((->) Int) Espero que tenham percebido a dúvida.. Qualquer ajuda é bem-vinda...Abraço
Rui Carlos Posted December 29, 2006 at 04:29 PM Report #73249 Posted December 29, 2006 at 04:29 PM o erro está na chamada da função 'd6' (na função 'geraCaract'), que devia estar a receber 2 inteiros. Rui Carlos Gonçalves
kAIOSHIN Posted December 29, 2006 at 07:23 PM Report #73312 Posted December 29, 2006 at 07:23 PM ok..obrigado. Só que agora quero usar os inteiros gerados aqui: modifiers :: Agente -> Modificador modifiers (a,b,c,d,_) = (truncate(((fromIntegral a)-10)/2), truncate(((fromIntegral b)-10)/2), truncate(((fromIntegral c)-10)/2), truncate(((fromIntegral d)-10)/2) ) *** Term : geraCaract *** Type : IO (Int,Int,Int,Int) *** Does not match : (Int,Int,Int,Int,Int) Ele gera IO (Int...) e não Int só... 😕
ricardo_bcl Posted December 29, 2006 at 09:14 PM Report #73340 Posted December 29, 2006 at 09:14 PM Meus amigos vou vos dar a conhecer uma função que "transforma" um IO a num a, mas que na cadeira em que eu descobri isto (Métodos de Programação 1 do 2º ano) dizia para não utilizar isto, por razões que agora não vou dizer... Mas o que é facto, é que dá jeito às vezes... lol Façam import System.IO.Unsafe E a dita função é unsafePerformIO, que é do tipo: unsafePerformIO :: IO a -> a Mas digo-vos que pode-se escrever os programas em haskell sem usar isto. Por acaso usei uma vez num caso em que não consegui dar-lhe a volta, mas o vosso trabalho de PF (o rpg) não precisa disto...
Guest id194 Posted December 30, 2006 at 12:56 AM Report #73374 Posted December 30, 2006 at 12:56 AM este tópico ficou assim um bocado confuso... só não percebo como é que ainda não solucionaram esse problema, a resposta está algures por aqui, eu já consegui resolver a minha dúvida com a ajuda do Rui Carlos. foi pelo messenger, ms de qq forma, tem neste tópico o exemplo que eu tava a ter problemas e o mesmo exemplo solucionado, portanto... a não ser que a vossa dúvida seja diferente.
kAIOSHIN Posted January 2, 2007 at 07:37 PM Report #74065 Posted January 2, 2007 at 07:37 PM Eu resolvi o meu problema, já acabei o trabalho... Mas só usando o unsafePerformIO é que consegui o que pretendia. Abraço
Rui Carlos Posted January 2, 2007 at 07:46 PM Report #74068 Posted January 2, 2007 at 07:46 PM ' timestamp='1167766676' post='74065']Eu resolvi o meu problema, já acabei o trabalho... Mas só usando o unsafePerformIO é que consegui o que pretendia. Abraço acho que os profs não vão achar muita piada à utilização dessa função... EDIT: isso está mesmo a funcionar? neste código module Teste where import System.IO.Unsafe import System.Random f=do res <- randomRIO (1,10) return res g=unsafePerformIO f ele só executa a função randomRIO uma vez!!! ou seja, a função g que devia dar valores aleatórios, gera sempre o mesmo valor em cada execução do ghci! *Teste> g1 *Teste> g 1 *Teste> g 1 *Teste> g 1 *Teste> g 1 *Teste> g 1 *Teste> g 1 *Teste> g 1 *Teste> f 10 *Teste> f 7 *Teste> f 9 *Teste> f 7 *Teste> f 9 *Teste> f 4 aconselho a leitura da documetação do GHC (ou do interpretador/compilador que estiverem a usar) para não terem surpresas: http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO Rui Carlos Gonçalves
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now