Ir para o conteúdo
mundo

Duvida com uma funçao usando filter e maps

Mensagens Recomendadas

mundo    4
mundo

Bom dia estou com uma pequena duvida, em que dando um numero, uma nota e uma lista alunonotas devolve o valor da nota, o que tenho é o seguinte e agradeço sugestões:

checkNotaWithNum :: Numero -> Nota -> AlunosNotas -> Valor
checkNotaWithNum a i l = map valo . filter val . map notval . filter (al l)
                         where al a (b,_,_,_) = a==b
                               notval (_,_,_,c)=c
                               val i ((x,y):t) = i==x
                               valo (x,y) = y

Desde ja agradeço

Cumprimentos

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

Os tipos não interessam para nada aqui porque a única operação usada entre eles, (==), está definida para todos os tipos básicos. Esses filters estão todos mal feitos, vai rever o tipo da função que o filter recebe como 1º parâmetro e vê se é igual ao que tens.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Polmax    0
Polmax

alunosnotas podia ser uma lista com tuplos ,com nome notas separadas , ou podia ser uma lista so com as notas e os numeros, acho que interessa bastante pra entender o que ele quer fazer

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

era assim definida


type Numero = Int
type Nome = String
type Insc = String
type Nota = String
type Valor = Int
type AlunoNotas = [(Numero, Nome, Insc, [(Nota,Valor)])]

Já consegui resolver o meu problema muito obrigado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

Bah estou a tentar melhorar isto mas estou com problemas, entao e o seguinte, tenho esta funçao que dado um numero e um AlunosNotas, que é uma turma, devolve o tuplo correspondente a informaçao do aluno na turma, para isso tenho o seguinte codigo

getAlunoWithNum :: Numero -> AlunosNotas -> AlunosNotas
getAlunoWithNum np t = filter (\(n,no,i,nts) -> n == np) t

Depois pretendo obter as notas dos alunos, em que consiste numa lista de tuplos (Nota,Valor), em que Nota e string e Valor é Int, Para isso tenho a seguinte função que devolve a lista com todas as (Nota,Valor) da turma:

getNotas :: AlunosNotas -> [(Nota,Valor)]
getNotas t = map (\(n,no,i,nts) -> nts) t

Bem o que pretendo e me falta e nao estou a conseguir consolidar, é dando o numero de aluno e a lista AlunosNotas, me devolve-se a lista [(Nota,Valor)] de um dado aluno, tenho o seguinte mas nao sei/percebo o porque de nao funcionar e como faze lo, se poderem ajudar agradeço, estou a fazer do seguinte modo:

checkNotasWithNum = getNotas . getAlunoWithNum

Cumprimentos

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

Como é que AlunosNotas é uma lista de tuplos com 2 elementos e nessas funções estás a usar como se tivessem 4?

Como é que no getNotas pegas numa lista de tuplos de 4 elementos e geras uma lista de tuplos de 2, se no map estás a dizer para gerar apenas uma lista de notas?

Isso compila sequer?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

Só nao compila isto

checkNotasWithNum = getNotas . getAlunoWithNum

os type's sao como defini ai em cima,

Peço desculpa tinha me esquecido do resto no AlunosNotas, ja editei :S

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

Sim, tipo a função eu tenho feita com recursividade, mas gostaria de saber como fazer assim com os filter e maps encadeados, porque vou precisar, para fazer uma função que permita consultar uma dada nota de um dado aluno, ou seja, pondo o numero e por exemplo "t1", ele devolva o valor de "t1",

para devolver as notas de um dado aluno tenho a funçao:

checkNotasWithNum :: Numero -> AlunosNotas -> [(Nota,Valor)]
checkNotasWithNum n [] = []
checkNotasWithNum n ((num,no,p,t):xs) |n == num = t
                                      |otherwise = checkNotasWithNum n xs

Mas como referi gostaria com os filter e maps, e ja agora se poderem dar uma sugestao para que caminho pegar para a funçao que pretendo fazer agradeço

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

O que tu estás a fazer não faz sentido e é ineficiente. Primeiro, no getAlunoWithNum, estás a devolver uma lista, dado um número de aluno. Ora o nº de aluno é único, não existem 2 repetidos, logo não faz sentido devolver uma lista, mas antes 1 tuplo com a informação do aluno. Mas como tens os tipos de dados mal representados para esse efeito, vês-te obrigado a fazê-lo (se bem que podias declarar o tuplo todo no tipo de retorno).

Para isso eu teria definido o tipo AlunoNotas para o seguinte:

type Aluno = (Numero,Nome,Insc,[(Nota,Valor)])
type AlunosNotas = [Aluno]

E ainda podias estruturar mais com um tipo Notas = [(Nota,Valor)].

Desta forma, a tua função getAlunoWithNum deve fazer aquilo que o nome sugere: devolver um Aluno, dado o seu número.

getAlunoWithNum :: Numero -> AlunoNotas -> Aluno

E para isto não há razão para usar o filter, porque o filter devolve uma lista. É claro que podes usar, mas devolver uma lista com um elemento e depois ir lá buscá-lo faz pouco sentido.

-- versão com filter
getAlunoWithNum num t = head $ filter (\(n,no,i,nts) -> n==num) t

-- versão sem filter
getAlunoWithNum' num (al@(n,no,i,nts):xs) | num==n = al
                                          | otherwise = getAlunoWithNum' num xs

Estou a assumir que a lista de alunos nunca é vazia e que o nº de aluno é válido, caso contrário o que deverias devolver era um Maybe Aluno. Isto claro, sem olhar para o problema como um todo, apenas para esta função. Porque se olhar para o problema todo, então nem vale a pena ter esta função. Qual o objectivo de obter a informação do aluno, depois obter a lista de todas as notas de todos os alunos e depois fazer...o quê? O que tu queres não é dar as notas de um dado aluno? Para quê esta confusão toda? A tua função checkNotasWithNum faz isso muito bem, sem espinhas, para quê desenhar soluções que não encaixam nos tipos de dados e que são mais ineficientes (quantas travessias é que tinhas de fazer à lista de alunos? 2? 3?). O filter poderia ser usado, por exemplo, para te dar a lista dos alunos cujas notas são negativas. Agora para isto parece-me completamente descabido.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

A minha intenção é, numa primeira funçao, (sim expressei me mal, a intenção e devolver o tuplo aluno de alunosnotas), e entao na primeira função do tuplo aluno retirar a informaçao relativo as notas, ou seja [(Nota,Valor)], introduzindo o numero de aluno e AlunosNotas, e depois noutra função, obter uma dada nota, introduzindo por exemplo:

>66696 "t1"

>75

Sendo que 66696 e o nº de aluno, "t1" a nota de [(Nota,Valor)], e o valor devolvido ou seja 75 o valor da nota que pretendo.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

Então basta fazeres uma função como a checkNotasWithNum que recebe uma lista [(Nota,Valor)] e o nome de uma nota (o tal "t1") e devolve o valor correspondente. Depois podes então encadear isto com a função checkNotasWithNum, que te devolve a lista [(Nota,Valor)] que passas como 1º argumento da nova função.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

Eu percebo o raciocinio, o meu problema hoje esta mesmo passar para o codigo, o Saraiva esta a dar me uma dor de cabeça dos diabos :wallbash:

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

Eu começo:

getValorNota :: [(Nota,Valor)] -> Nota -> Valor
getValorNota [] _ = ...
getValorNota ((n,v):nts) nt ...

getValorNotaAluno :: Numero -> Nota -> AlunoNotas -> Valor
getValorNotaAluno num nota ns = ...

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

Fica algo tipo:

getValorNota :: [(Nota,Valor)] -> Nota -> Valor
getValorNota [] _ = 0
getValorNota ((n,v):nts) nt | n == nt = v
                            | otherwise = getValorNota nts nt

--getValorNotaAluno :: Numero -> Nota-> AlunosNotas -> Valor
getValorNotaAluno num nota ns = getValorNota ns

Não estou a perceber é esta parte da função getValorNotaAluno, como é que vou lhe dar a parte só [(Nota,Valor)]?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
mundo    4
mundo

A combinação deles é feitas tipo isto:

getValorNotaAluno num nota ns = checkNotasWithNum . getValorNota ns

Quero eu dizer com uso do operador "." ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Baderous    31
Baderous

Esquece a composição de funções.

checkNotasWithNum pega num Numero, num AlunosNotas e dá um [(Nota,Valor)].

getValorNota pega numa [(Nota,Valor)], numa Nota, e dá um Valor.

Vê se agora já chegas lá.

Partilhar esta mensagem


Link 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