Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Miguel Correia

Exercicio Data types

Mensagens Recomendadas

Miguel Correia

Boa Tarde ,

o problema é o Seguinte :

Considere o seguinte tipo de dados que descreve a informação de um extracto bancário. Cada valor deste tipo indica o saldo inicial e uma lista de movimentos. Cada Movimento é representado por um triplo que indica data da operação , operação e quantia movimentada. (valores sempre positivos)

data Movimento = Credito Float | Debito Float
data Extracto = Ext Float [(Data, String, Movimento)]

--a) que produz uma lista de todos os movimentos (creditos ou debitos) superiores a um determinado valor.
extValor :: Extracto -> Float -> [Movimento]
extValor (Ext _ [_]) 0 = []
extValor (Ext x l) x1 | x >= x1 = [(Credito (x-x1))]
                     | x < x1 = [(Debito (abs (x1-x)))]

isto não dá qualquer tipo de erro , mas acho que só faz para um caso e nao estou a ver como fazer para todos .

Aguardo Sugestões :)

Cumps

Miguel Correia

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Baderous

Não tentei perceber muito bem o teu raciocínio porque pelo que vi parece-me que estás a fazer coisas desnecessárias bem como a construir mal a lista.

No caso base tens de testar o caso em que não há movimentos, ou seja, a lista de movimentos é vazia (e não uma lista com um elemento como indicaste). Neste caso o valor do 2º argumento é irrelevante e não 0 como tu indicaste.

Para o caso recursivo não precisas de andar a fazer contas com o valor inicial da conta e os débitos/créditos, isso não interessa para nada, apenas queres obter a lista dos movimentos superiores a um dado valor (e lembra-te que são sempre positivos, logo o abs nem era preciso).

Portanto, o meu conselho é:

1) Fazer um deriving Show no tipo dos Movimentos para poderes visualizá-los quando testares essa função;

2) Definir uma função que, dado um Movimento e um valor, indica se ele é ou não superior a esse valor;

3) Reescreveres a função extValor de acordo com as dicas que te dei e, para o caso em que há movimentos a testar, testas cada um deles com a função definida em 2) e em função do resultado, adicionas ou não o movimento respectivo à lista final, fazendo a invocação recursiva posteriormente com o resto da lista.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Miguel Correia

Tipo isto ?

extValor :: Extracto -> Float -> [Movimento]
extValor (Ext _ []) _ = []
extValor (Ext x ((_,_,(Credito y)):t) ) n | (superior (Credito y) n) = (Credito y) : (extValor (Ext x t) n)
                                         | otherwise = (Debito y) : (extValor (Ext x t) n)

superior :: Movimento -> Float -> Bool
superior [] _ = False
superior (Credito x) n = if x >= n
then True
else False

Está a dar-me este erro :

ExerDatas.hs:73:24:

No instance for (Show Movimento)

arising from the 'deriving' clause of a data type declaration

Possible fix:

add an instance declaration for (Show Movimento)

or use a standalone 'deriving instance' declaration,

so you can specify the instance context yourself

When deriving the instance for (Show Extracto)

Editado por Rui Carlos
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Baderous

Mas tipo , na funçao auxiliar que vou criar , no Movimento , verifico com Credito ou Debito?

Tens de verificar os 2, tens de definir a função para os 2 construtores do tipo Movimento (Credito e Debito).

Esse erro que estás a obter eu disse-te como resolver no ponto 1).

E o que estás a fazer não faz sentido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Miguel Correia

Isto?

extValor :: Extracto -> Float -> [Movimento]
extValor (Ext _ []) _ = []
extValor (Ext x ((_,_,m):t) ) n | superiorC m n = m : extValor (Ext x t) n
                               | superiorD m n = m : extValor (Ext x t ) n


superiorC :: Movimento -> Float -> Bool
superiorC _ 0 = True
superiorC (Credito x) n = if x >= n
then True
else False

superiorD :: Movimento -> Float -> Bool
superiorD _ 0 = True
superiorD (Debito x) n = if n > x then True else False

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Baderous

Estás mais perto.

A função que testa se o valor é superior não precisa de ser uma função distinta para cada construtor do tipo Movimento, pode ser apenas uma única:

-- determina se um dado movimento é superior a um dado valor
movSupVal :: Movimento -> Float -> Bool
movSupVal (Credito c) v = c >= v
movSupVal (Debito d) v = d >= v

Depois na extValor invocas esta função para comparar o m com o n e, se for superior, adicionas o m à lista como já estás a fazer. Se não for então não adicionas, apenas invocas recursivamente a função.

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.