Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
Miguel Correia

Exercicio Data types

Recommended Posts

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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites
Miguel Correia

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

Share this post


Link to post
Share on other 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)

Edited by Rui Carlos
geshi

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites

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
Sign in to follow this  

×

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.