Jump to content
nuno35

Tipo de dados e propriedades

Recommended Posts

nuno35

Boa tarde tenho este tipo de dados que pode ter uma subarvore e tenho a seguite duvida

data HTML = Div [html] | Texto String | Negrito String 

quero fazer uma funcao que passa o o Texto para negrito e tenho este codigo que nao sei se esta correto

converter _ _ = _ _
converter Texto x = Negrito x

e tenho de fazer uma propriedade que verifique que a arvore principal é mais profunda que as subarvores e a minha duvida é como aceder as sub arvores tenho:
(supoe-se que tenho uma funcao profundidade)

prop_maior_arvore :: HTMl -> Property
prop_maior_arvore html = profundidade html > profundidade (tenho aqui a duvida de como aceder a subarvore de html)

Desde já obrigado
 

Edited by nuno35

Share this post


Link to post
Share on other sites
thoga31

Rapidamente acerca da primeira função:

  1. Os pattern matching são sensíveis à ordem, ou seja, se os argumentos corresponderem a um determinado pattern, todos os seguintes são ignorados. Nesse sentido, o teu segundo pattern nunca será executado pois o primeiro é sempre verdadeiro, quaisquer que sejam os dados passados por argumento.
  2. No teu pattern de "outros casos", _ _ = _ _ não faz sentido pois o Haskell não sabe o que devolver. _ é usado para definir "qualquer dado de entrada" e não para determinar dados de saída (não tem, sequer, qualquer sentido a nível sintáctico).

E acerca do tipo de dados:

  • O que é Div? Onde está definido html? Porquê html entre []?

Cumprimentos.

Edited by thoga31
Formatação

Knowledge is free!

Share this post


Link to post
Share on other sites
nuno35

Basicamente era para ele devolver a mesma coisa que receber mas nao podendo por _ como dado de saída basicamente tenho de porigual a entrada e saída para cada caso a nao ser o que quero mudar.

no tipo de dados o Div

 é basicamente uma sub arvore do html

Share this post


Link to post
Share on other sites
thoga31
5 horas atrás, nuno35 disse:

no tipo de dados o Div


 é basicamente uma sub arvore do html

Eu percebi isso, mas achas que está bem definido? Não te está a dar nenhum erro no GHCi?

 

5 horas atrás, nuno35 disse:

Basicamente era para ele devolver a mesma coisa que receber mas nao podendo por _ como dado de saída basicamente tenho de porigual a entrada e saída para cada caso a nao ser o que quero mudar.

Expliquei acima porque isso não faz sentido em Haskell.

Se queres ignorar todos os restantes casos, tens de explicitar os argumentos de entrada e explicitar a forma como eles são devolvidos pela função.

converter (Texto xs) = Negrito xs
converter ys = ys

 

P.S.: Sugestão adicional para podermos "ver" o HTML com que trabalhamos:

instance Show HTML where
    show (Texto xs)   = "Texto \""   ++ xs     ++ "\""
    show (Negrito xs) = "Negrito \"" ++ xs     ++ "\""
    show (Div h)      = "Div ("      ++ show h ++ ")"

 


Knowledge is free!

Share this post


Link to post
Share on other sites
nuno35

Nao estou a correr o tipo de dados isto é um exercicio de um examee é assim que esta definido nao devia estar entre parenteses rectos?

Ja percebi nao posso utilizar o _ por ele nao saber o que devolver eu nao estava era encontrar ua maneira de compactar os restantes casos em vez de escrever um a um, o show eu a tinha feito.

Eu ja tentei foi usar os parenteses rectos na property 

prop_maior_arvore :: HTMl -> Property
prop_maior_arvore html = profundidade html > profundidade div[html]

mas nao esta correto

Share this post


Link to post
Share on other sites
thoga31

Atenção, o Haskell é case-sensitive, portanto div é diferente de Div. A capitalização do identificador tem, aliás, significado sintáctico em Haskell. O mesmo vale para HTML, html e (conforme tens escrito) HTMl.

De seguida, não, html entre parêntesis rectos naquele caso não me parece fazer sentido. Para conseguir correr o código, tive de definir assim:

data HTML = Div HTML | Texto String | Negrito String

Por fim, qual a definição de profundidade? Tens alguma função que te permita extrair os elementos de um HTML? Tal seria útil, porventura.


Knowledge is free!

Share this post


Link to post
Share on other sites
nuno35

sim essa funcao ja é definida no enunciado basicamente se HTML for apenas Texto ou Negrito a profundidade é 1 mas é uma funcao que nao é feita por nos é apenas descrito o seu funcionamento pelo que percebi os parenteses rectos é que nao fazem sentido 

prop_maior_arvore :: HTMl -> Property
prop_maior_arvore HTML = profundidade HTML > profundidade Div HTML

 

Share this post


Link to post
Share on other sites
thoga31

Com a informação que tenho, o melhor que posso propor é isto:

maior x@(Div xs) = prof x > prof xs

 


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

@nuno35, vamos por partes.

Podemos começar pelo teu tipo de dados. Aquela variável html não está ali a fazer nada, e o compilador não sabe o que ela representa (porque na realidade não representa nada). O que tu pretendes com o construtor Div é dizer que dentro dele pode haver uma lista de elementos HTML... logo, o correcto é:

data HTML = Div [HTML]
          | Texto String
          | Negrito String

Repara que utilizo HTML tanto à esquerda como à direita do =, porque o nosso tipo de dados é, de certa forma, recursivo.

Passamos então para a implementação da typeclass Show, que o @thoga31 falou; podes utilizar a solução que te foi dada, ou então utilizar deriving Show para automatizar o processo.

 

Passemos à função converter. O teu tipo de dados HTML tem 3 construtores, como achas que deve comportar-se em cada caso? Vou resolver o primeiro por ti, e tentarás completar os restantes:

converter (Negrito x) = Negrito x
converter (Texto x)   = ...
converter (Div elems) = ...

Uma dica: no caso do construtor Div lembra-te que podes aceder aos elementos dentro dele como se fosse uma lista... logo, podes aplicar a função converter a cada um deles facilmente com um map.

 

E agora vamos à tal "propriedade". Desconheço o tipo de dados Property, mas vamos para já assumir que deveria ser um Bool.

Para conseguires testar se a profundidade de uma árvore é maior que outra, temos primeiro que ter uma forma de saber a profundidade. Vamos construir essa função:

profundidade (Div elems) = 1 + ...
profundidade _           = 0

Sabemos que a profundidade de um Div é a soma de 1 com a profundidade da maior árvore nele contida. Assumimos que os restantes construtores (Texto e Negrito) têm profundidade 0. Deixo para ti a tarefa de completar a função acima (dica: podes utilizar as funções map e maximum para solucionar o problema).

 

Uma vez tendo esta função profundidade, podemos testar facilmente a propriedade que pretendias:

prop_arvore_maior_que_subarvores x@(Div xs) = profundidade x > (maximum (map profundidade xs))

A notação x@(Div xs) permite-nos referir-nos ao argumento na sua totalidade (x) e desconstruí-lo (Div xs) em simultâneo.

 

Se leres este post e tentares completar os espaços... penso que consegues compreender o raciocínio e perceber como fazer isto por ti. Vai expondo as tuas dúvidas.

  • Vote 1

Share this post


Link to post
Share on other sites
nuno35

ok entao a funcao converter com a dica que deste parece me assim:

converter (Negrito x) = Negrito x
converter (Texto x)   = Negrito x
converter (Div elems) = map converter elems

a funçao profundidade nao é necessario mas vou faze la

profundidade (Div elems) = 1 + maximum (map profrundidade elems)
profundidade _           = 0

quanto a propriedade tenho umas certas duvidas entao tenho de receber dois argumentos a arvore e a lista de sub arvores 

prop_arvore_maior_que_subarvores x@(Div xs) = profundidade x (arvore principal) > (maximum(map profundidade xs)) (fico com uma lista da profundidade de todas as sub arvores e tiro o maximo dessa lista)


acho que ja percebi so continuo sem perceber a diferença de x@(Div xs) para x (Div xs) nao percebo bem qual é a funçao do arroba ali

Desde ja obrigado

Share this post


Link to post
Share on other sites
thoga31
20 minutos atrás, nuno35 disse:

continuo sem perceber a diferença de x@(Div xs) para x (Div xs) nao percebo bem qual é a funçao do arroba ali

Considera o seguinte exemplo.

Tens uma lista de valores e pretendes uma função que devolva uma lista de tuplos cujo segundo elemento contenha o primeiro elemento da lista e o primeiro tenha o comprimento da lista completa. Terás qualquer coisa como isto:

foo [] = []
foo l@(x:xs) = (length l, x) : foo xs

Ao executar, terás algo assim:

Prelude> foo ['a','b','c','d']
[(4,'a'),(3,'b'),(2,'c'),(1,'d')]

Portanto, desconstrui o argumento da seguinte forma:

  • l é o nome da lista completa;
  • x é o primeiro elemento da lista;
  • xs é o resto da lista.

Isto é um único argumento, o que é completamente diferente de l (x:xs), que são 2 argumentos.

Por exemplo, quando passamos ['a','b','c','d'] à função foo, o que acontece é o seguinte:

  • l identifica a lista completa (l = ['a','b','c','d']);
  • x identifica o primeiro elemento (x = 'a');
  • xs identifica o resto da lista (xs = ['b','c','d']).

 

Aplicando ao teu caso, quando fazemos x@(Div xs), estamos a desconstruir o argumento de uma forma semelhante. Se passares à função o argumento Div [Negrito "bar"], o argumento será constituído da seguinte forma:

  • x identifica todo o argumento (x = Div [Negrito "bar"]);
  • xs só contém o que está dentro do Div (ou seja, xs = [Negrito "bar"]).

 

Cumprimentos.


Knowledge is free!

Share this post


Link to post
Share on other sites
nuno35

ahh okok ja entendi é apenas um argumento mas consigo aceder a varias coisas eu ja sabia o (x:xs) desconhecia que podiamos por tambem a variavel com a lista completa incluido em apenas um argumento.

Edited by nuno35

Share this post


Link to post
Share on other sites
pwseo

@nuno35,

A tua definição de converter para parâmetros tipo Div elems está errada (dica: qual o tipo de dados de map converter elems?)

A tua questão sobre a função transposta tem alguma relação com o discutido agora? Repara que o título do tópico é incrivelmente geral, mas não é suposto os tópicos mudarem de tema frequentemente -- fica mais difícil para quem vem de fora e tenta seguir o raciocínio.

Share this post


Link to post
Share on other sites
nuno35

nao, nao tem deixemos esse problema de lado

elems é uma lista de HTML e estou a aplicar a funcao converter a essa lista 

converter (Negrito x) = Negrito x
converter (Texto x)   = Negrito x
converter (Div elems) = Div (map converter elems)

 

Edited by nuno35

Share this post


Link to post
Share on other sites
pwseo

Agora sim a tua definição de converter está correcta (na resposta anterior faltava-te um Div antes de map converter elems)

Posto isto, ainda tens dúvidas em relação à tua função transposta? Se sim, porque não abrir um tópico sobre «Transposição de uma matriz» ou algo semelhante? :)

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

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