mundo Posted November 21, 2011 at 08:35 PM Report #422042 Posted November 21, 2011 at 08:35 PM Boas noite, tenho um exercicio feito na aula em que nao estou a perceber isto bem, ate o proprio prof se trocou lol, poderiam me ver o que está a dar conflito com o seguite codigo emStock :: Produto -> Stock -> Qtd emStock np st = q where pds = produto nt st q = if pds == [] then 0 else qdd (head pds) qtd (_,_,qt) = qt produto :: Produto -> Stock -> Stock produto n s = filter (p n) s where p nome (no,p,q) = nome == no o erro e o seguinte "parse error on input `=' ", está a acontecer aqui nesta parte do código else qdd (head pds) qtd (_,_,qt) = qt Se alguem me poder ajudar fico desde ja agradecido. Os melhores cumprimentos
Rui Carlos Posted November 21, 2011 at 09:14 PM Report #422052 Posted November 21, 2011 at 09:14 PM Será que o qtd (_,_,qt) = qt não devia estar na linha seguinte? Esse código está muito incompleto, pelo que é difícil identificar o erro. Rui Carlos Gonçalves
mundo Posted November 21, 2011 at 09:46 PM Author Report #422068 Posted November 21, 2011 at 09:46 PM Não rui costa, se preferires coloco aqui o enunciado, esse código foi feito pelo professor, e ele queria fazer o exercicio ultilizando somente funçoes de ordem superior sem recursividade, eu nao perceber o que ele fez e o compilador tambem se queixa lol. O enunciado é o seguinte: "Considere que a informaçao sobre um stock de uma loja esta armazenada numa lista de tuplos (com o nome do produto, o seu preço unitario, e a quantidade em stock desse produto) de acordo com as seguintes declaraçoes de tipos: type Stock = [(Produto,Preco,Quantidade)] type Produto = String type Preco = Float type Quantidade = Float Defina as seguintes funçoes de manipulaçao e consulta do stock: ii. emStock::Produto->Stock->Quantidade, que indica a quantidade de um dado produto existente em stock." Os melhores cumprimentos
Rui Carlos Posted November 21, 2011 at 10:05 PM Report #422070 Posted November 21, 2011 at 10:05 PM Quase que apostava como falta lá uma quebra de linha (quer porque o '=' não faz sentido ali, quer porque qtd não foi definido previamente). Qual é a assinatura da função qdd? Quantos argumentos é suposto ter? O código está errado. Há várias formas de resolver o erro que está a dar, mas com a informação disponível é difícil saber qual a forma correcta. Rui Carlos Gonçalves
mundo Posted November 21, 2011 at 10:20 PM Author Report #422077 Posted November 21, 2011 at 10:20 PM Isto é uma função local, o stor não nos deu definiçao da funçao simplesmente escreveu no quadro e disse para depois experimentarmos, eu ja na aula achei estranho, e em casa pus me a pensar, e nao entendo mesmo este exercicio, ate que concordo contigo quanto a estar incompleto, mas segundo ele estava bem, agora nao sei xD
pwseo Posted November 22, 2011 at 02:18 AM Report #422115 Posted November 22, 2011 at 02:18 AM O Rui Carlos tem razão: o código está mal. Porque não fazer isso de forma mais simples? emStock :: Produto -> Stock -> Quantidade emStock p = sum . map qtd . filter (fn p) where qtd (_,_,q) = q fn a (b,_,_) = a == b Mesmo assim, parece-me que a versão correcta do que tens aí seria algo como: emStock :: Produto -> Stock -> Quantidade -- aqui é "Quantidade" e não "Qtd" emStock np st = q where pds = produto np st -- aqui tinhas um erro.. dizia "nt" onde devia dizer "np" q = if pds == [] then 0 else qtd (head pds) -- aqui tinha outro erro: é "qtd" e não "qdd" qtd (_,_,qt) = qt -- e isto era de facto uma linha separada produto :: Produto -> Stock -> Stock produto n s = filter (p n) s where p nome (no,p,q) = nome == no EDIT: na minha sugestão troquei sum por head que conceptualmente faz mais sentido. EDIT2: voltei a colocar sum porque head não lida com listas vazias.
mundo Posted November 23, 2011 at 12:29 PM Author Report #422370 Posted November 23, 2011 at 12:29 PM Agradeço o esclarecimento e desde já peço desculpa pela demora. Estou com duvida noutro exercicio está me a dar as voltas a cabeça poq nao encontro o erro, e nao vejo necessidade de criar outro topico, o que é pedido é o seguinte: "Seleciona os alunos que passaram (i.e., a nota da Parte I não inferior a 8, e a soma das nota da Parte I e II é superior ou igual a 9,5)." Eu tenho o seguinte código: type Aluno = (Numero, Nome, ParteI, ParteII) type Numero = Int type Nome = String type ParteI = Float type ParteII = Float type Turma = [Aluno] --(b) alunosPassaram :: (Turma -> Bool) -> Turma alunosPassaram l = filter passar l where passar (_,_,p1,p2) = ((p1 >= 8) && (p1+p2 >= 9.5)) Aguardo resposta e desde já agradeço
pwseo Posted November 23, 2011 at 12:45 PM Report #422374 Posted November 23, 2011 at 12:45 PM mundo, Provavelmente a assinatura da função será algo como: alunosPassaram :: Turma -> [Aluno] Da forma que está, a tua função aceita como argumento uma função que converte uma Turma em Bool (Turma -> Bool), e devolve uma Turma (não faz muito sentido). O que tu queres é receber uma Turma como argumento, e dessa turma filtrar os alunos que passaram, e devolver essa lista de alunos (Turma -> [Aluno]). Nota: eu sei que Turma é o mesmo que [Aluno], mas assim a assinatura fica mais explícita "aceita uma Turma inteira e devolve apenas uma lista de Alunos". Adenda: Quando achares que resolveste uma função correctamente e mesmo assim não funciona, experimenta tirar a assinatura dela. Faz reload no ghci e depois :t alunosPassaram. *Main> :t alunosPassaram alunosPassaram :: (Ord t2, Fractional t2) => [(t, t1, t2, t2)] -> [(t, t1, t2, t2)] Depois é só reparares que [(t, t1, t2, t2)] é um sinónimo de Turma (ou [Aluno]). E pronto, substituis e tens aí a assinatura correcta (removes o Ord t2, Fractional t2 também).
mundo Posted November 23, 2011 at 07:40 PM Author Report #422452 Posted November 23, 2011 at 07:40 PM Hum acho que fiquei esclarecido, estou com alguns outros erros, mas é dentro do mesmo por isso vou tentar resolver, qualqer duvido venho cá perguntar. E obrigado por tudo 😕
mundo Posted November 23, 2011 at 08:16 PM Author Report #422465 Posted November 23, 2011 at 08:16 PM Peço desculpa pelo doble post, mas estou aqui com uma duvida face ao significado de uma funçao caso me possam explicar agradeço, sei que esta nao é a melhor opçao, o objectivo disto e eu perceber melhor a assinatura desta mesma funçao, aqui vai o codigo: mediaNotas :: [(Nome, Float)] -> Float --sei que a assinatura nao esta correcta mediaNotas l = let s = foldr (\(_,_,n1,n2) v -> n1+n2+v) 0 l n = foldr (\ _ v -> v+1) 0 l in s/n
pwseo Posted November 23, 2011 at 08:52 PM Report #422480 Posted November 23, 2011 at 08:52 PM mundo, Antes de mais, tens um erro na tua função: quando dizes n1+n2+v deveria ser ((n1 + n2) / 2) + v porque (assumo eu), cada teste conta 50% para a nota de cada aluno (logo, tens que somar os dois testes e dividir por dois para obter a média desse aluno). A parte "complicada" desta função é a utilização da foldr. A foldr essencialmente reduz uma lista da direita para a esquerda, aplicando uma função binária (que aceita 2 argumentos) a dois elementos da lista de cada vez. foldr (+) 0 [1..3] é o mesmo que (1+(2+(3+0))) (Aqui vemos onde entra o zero que passas à função; é usado para servir de 2º argumento à primeira aplicação da função). Depois da primeira aplicação, cada resultado obtido serve de 2º argumento à próxima aplicação (e o 1º argumento é o elemento seguinte na lista, da direita para a esquerda). No teu caso, tens ali uma função anónima que recebe um Aluno e um número (v), e soma a média das notas do aluno ao v. Agora tens de pensar nisto de forma recursiva. Imagina que tens 2 alunos: alunos = [(1, "Pedro", 10, 11), (2, "João", 13, 12)] :: [Aluno] fn = \ (_,_,n1,n2) v -> ((n1+n2)/2) + v -- esta é a função que usaste em cima, corrigida para obter a média do aluno se fizeres foldr fn 0 alunos, vai acontecer o seguinte: 1º passo: fn (1, "Pedro", 10, 11) (fn (2, "João", 13, 12) 0) 2º passo: fn (1, "Pedro", 10, 11) 12.5 3º passo: 11.5 O importante é ganhares uma "intuição" de como funciona a foldr (assumindo que sabes o que são funções anónimas, claro). Se não era esta a dúvida, peço desculpa, mas foi o que pensei ser mais complexo 🙂 PS.: a assinatura seria, como deves imaginar, mediaNotas :: [Aluno] -> Float.
mundo Posted November 23, 2011 at 10:05 PM Author Report #422509 Posted November 23, 2011 at 10:05 PM Pedro kun, da maneira que fizes te se nao me engano e percebi bem, esta a calcular a media individual com que aluno termina certo? O que eu necessito e a media de uma turma, dai receber so [(Nome,Float)] em que Nome é o nome do aluno e o Float a nota com que o aluno termina a disciplina, e devolver um Float que é a media total da turma, da maneira como fizes te ja tenho resolvido e fiz assim com funçoes anonimas tambem 😕 Uma questão e peço desculpa pelo edit, o tal numero v, e algo que vai se adicionando, que vai funcionar como uma especie de acumulador de valores, ou nao tem nada a ver com isso? nao consigo perceber bem isso.
pwseo Posted November 23, 2011 at 10:08 PM Report #422511 Posted November 23, 2011 at 10:08 PM mundo, Mas a função que tu escreveste aceita uma lista de Alunos e devolve um Float. Ora, se um Aluno é (Numero, Nome, ParteI, ParteII), a assinatura da função não pode ser [(Nome,Float)] -> Float, mas sim [Aluno] -> Float ou então [(Numero, Nome, ParteI, ParteII)] -> Float. E sim, eu calculo a média individual de cada aluno, senão o resultado final (a média dos alunos todos) será um valor entre 0 e 40, em vez de ser entre 0 e 20. EDIT: o v é o valor inicial para a função foldr. É usado para a primeira soma que a função faz.
mundo Posted November 23, 2011 at 10:21 PM Author Report #422516 Posted November 23, 2011 at 10:21 PM Hum clarissimo, muito obrigado, tens sido uma grande ajuda 😕
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