Jump to content

Recommended Posts

Posted

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

Posted

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

Posted

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.

Posted

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

Posted

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.

Posted

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

Posted

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).

Posted

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 😕

Posted

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
Posted

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.

Posted

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.

Posted

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.

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
×
×
  • 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.