skp9 Posted December 7, 2015 at 08:49 PM Report Share #590453 Posted December 7, 2015 at 08:49 PM (edited) Boa tarde! Gostaria que me ajudassem aqui numa pequena coisa num exercício em Haskell. É o seguinte : Para armazenar uma agenda de contactos telefónicos e de correio electrónico definiram-se os seguintes tipos de dados. Não existem nomes repetidos na agenda e para cada nome existe uma lista de contactos. data Contacto = Casa Integer | Trab Integer | Tlm Integer | Email String type Nome = String type Agenda = [(Nome, [Contacto])] Depois aparecem os seguintes exercícios: Defina a função acrescEmail :: Nome -> String -> Agenda -> Agenda que, dado um nome, um email e uma agenda, acrescenta essa informação na agenda. Defina a função verEmails :: Nome -> Agenda -> Maybe [string] que, dado um nome e uma agenda, retorna a lista dos emails associados a esse nome. Se esse nome não existir na agenda a função ao deve retornar Nothing. Defina a função consTelefs :: [Contacto] -> [integer] que, dada uma lista de contactos, retorna a lista de todos os números de telefone dessa lista (tanto telefones fixos como telemoveis). Defina a função casa :: Nome -> Agenda -> Maybe Integer que, dado um nome e uma agenda, retorna o numero de telefone de casa (caso exista). Ora bem, a minha dúvida não está em como resolver os exercícios uma vez que tenho as resoluções mas em como testa-los. Por exemplo, em exercicios de matrizes eu definia: type Mat a = [[a]] e depois para testar criava uma matriz do genero: m1 :: Mat Int m1 = [[1,2,3],[0,4,5],[0,0,6]] e sempre que queria testar usava essa matriz. Eu queria saber como criar um agenda (neste caso) de modo a que dê para testar. Já tentei imensas vezes e não consegui. E outra duvida, na alinea c), tenho a resolução: consTelefs :: [Contacto] -> [integer] consTelefs [] = [] consTelefs ((Casa x):ts) = x : (consTelefs ts) consTelefs ((Trab x):ts) = x : (consTelefs ts) consTelefs ((Tlm x):ts) = x : (consTelefs ts) consTelefs (_:ts) = consTelefs ts não há outra maneira de resolver o exercicio sem tantas linhas de codigo? Edited December 7, 2015 at 09:40 PM by pwseo Remodelação completa do post para cumprir as regras. Link to comment Share on other sites More sharing options...
pwseo Posted December 7, 2015 at 09:42 PM Report Share #590456 Posted December 7, 2015 at 09:42 PM skp9, Antes de publicares o post deverias ter reparado que estavas a colocar fundo escuro e letras claras (completamente desnecessário) e, além disso, todo o código estava desformatado. Desta vez corrigi todo o teu post de modo a que os outros membros consigam lê-lo confortavelmente para te ajudar; da próxima vez não será assim. Link to comment Share on other sites More sharing options...
pwseo Posted December 7, 2015 at 10:01 PM Report Share #590457 Posted December 7, 2015 at 10:01 PM skp9, Que erros obténs quando tentas criar uma Agenda? De que modo estás a tentar fazê-lo? (se não mostras, não podemos dizer-te o que estás a fazer de errado). De qualquer modo, criares uma Agenda precisas apenas de utilizar os respectivos construtores de dados. Agenda é apenas uma lista de tuplos, pelo que é simples criá-la; o problema surge nos Contactos, nesses precisas de utilizar os seus construtores: -- Um nome sem contactos associados pwseo :: (Nome, [Contacto]) pwseo = ("pwseo", []) -- Um nome com 2 contactos skp9 :: (Nome, [Contacto]) skp9 = ("skp9", [ Email "skp9@skp.xyz", Tlm 990000000 ]) -- Uma agenda: agenda :: Agenda agenda = [ pwseo, skp9 ] Obviamente, isso podia ser criado directamente assim: agenda :: Agenda agenda = [ ("pwseo", []), ("skp9", [ Email "skp9@skp.xyz", Tlm 990000000 ]) ] Quanto à tua segunda questão: sim, é possível utilizar menos código. No entanto, é preciso saber o que já sabes de Haskell. Já utilizaste as funções map, filter e semelhantes? Link to comment Share on other sites More sharing options...
skp9 Posted December 8, 2015 at 12:24 AM Author Report Share #590462 Posted December 8, 2015 at 12:24 AM Quanto à tua segunda questão: sim, é possível utilizar menos código. No entanto, é preciso saber o que já sabes de Haskell. Já utilizaste as funções map, filter e semelhantes? Antes de mais peço desculpa pela forma como coloquei o post. Muito obrigado pela resposta! Quanto às funções de ordem superior, já usei o map, filter, foldr... aquelas mais básicas. É a primeira vez que estou a programar, e daí as minhas dúvidas poderem ser um bocado "básicas" Link to comment Share on other sites More sharing options...
Solution pwseo Posted December 8, 2015 at 01:01 PM Solution Report Share #590467 Posted December 8, 2015 at 01:01 PM Então vamos pensar da seguinte forma: tu queres converter uma lista de Contacto numa lista de Integer. Para isso, precisamos de filtrar a lista excluindo os Emails e depois extrair os números, correcto? Vamos pensar na função de extracção: extract :: Contacto -> Integer extract (Tlm n) = n extract (Trab n) = n extract (Casa n) = n Se reparares bem, esta função não funciona com todo o domínio de valores do tipo Contacto pois não definimos o que acontece se lhe passarmos um Email. No entanto, essa situação não se irá verificar, pelo seguinte: isPhone :: Contacto -> Bool isPhone (Email _) = False isPhone _ = True Se pensares bem, as duas funções que acabámos de definir podem ser úteis noutros contextos do teu programa; é simples imaginar situações em que precisas de extrair o número de telefone de um contacto ou determinar se esse contacto é um número de telefone ou não. E agora vamos à função principal. Temos que a ler da direita para a esquerda: filtrar a lista aplicando isPhone e, na lista resultante, aplicar extract: consTelefs :: [Contacto] -> [integer] consTelefs = map extract . filter isPhone Claro que também podes juntar tudo, mas como eu disse acima, as funções isPhone e extract (que poderias até denominar extractPhoneNumber) parecem-me demasiado úteis para as deixar como funções acessórias dentro da consTelefs: consTelefs :: [Contacto] -> [integer] consTelefs = map extract . filter isPhone where extract (Tlm n) = n extract (Trab n) = n extract (Casa n) = n isPhone (Email _) = False isPhone _ = True Sei que o número de linhas de código desta última versão não diminuiu em relação ao teu código, mas é muito mais claro o que está a acontecer, visto que podemos ler apenas uma linha de código e compreender todo o raciocínio (os nomes extract e isPhone são auto-explicativos). Link to comment Share on other sites More sharing options...
skp9 Posted December 18, 2015 at 09:05 PM Author Report Share #590853 Posted December 18, 2015 at 09:05 PM Muito obrigado! Link to comment Share on other sites More sharing options...
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