Jump to content

[Haskell] Verificar se um elemento está numa lista


Guest id194
 Share

Recommended Posts

O enunciado diz o seguinte para ser feito recursivamente:

"Dada uma lista e um elemento, verifique se esse elemento está contido na lista"

Esta é última alínea deste exercício, em todas as outras, as listas são referidas como sendo listas de inteiros, mas não neste caso. Anyway... se for com uma lista de inteiros e verificar se o inteiro está na lista, óptimo, já consegui fazer isso da seguinte forma:

elemc :: ([int], Int) -> Bool
elemc ([], _) = False
elemc ((x:xs), y) = if x == y then True else elemc (xs, y)

*S3_Tarefa1> elemc ([4,7,21,6,3,56,2,5,254], 21)

True

*S3_Tarefa1> elemc ([4,7,21,6,3,56,2,5,254], 28)

False

A minha questão é, é possível fazer algo do genero sem definir a lista e o elemento como inteiro, por exemplo, se a função tive a assinatura "elemc :: ([a], a) -> Bool", é possível ser feito? E depois chamar a função tipo "elemc ([4, 6, "bla", 7.4, 'X'], 'X')" obtendo "True". Ou isto não é possível? Eu ainda tentei inventar um pouco, mas não consegui fazer nada, daí, assumir que o exercício se referia a inteiros...

Link to comment
Share on other sites

em Haskell as lista não são polimorficas!!

tu podes ter '[a]', mas isto quer dizer que o 'a' é um tipo qualquer, mas é sempre o mesmo.

ou seja, ou temos listas de inteiros, ou de strings, ou de chars ou de outra coisa qualquer desde que seja tudo do mesmo tipo.

a função que precisas já está definida no Prelude ('elem') de forma a funcionar para qualquer tipo de dados.

para a tua dar para qualquer tipo de dados só tens que fazer isto:

elemc :: Eq a => ([a],a) -> Bool
elemc ([], _) = False
elemc ((x:xs), y) = if x == y then True else elemc (xs, y)

o 'Eq a =>' significa que o tipo 'a' tem que implementar a classe 'Eq', ou seja, o tipo 'a' tem a função '==' definida (necessário pois ela é usada em 'x==y').

já agora, acho que devias definir a função antes como 'a -> [a] -> Bool', pois torna-se mais fácil de usar em programação pointfree.

Link to comment
Share on other sites

axo k já percebi, posso usar 'a' mas só posso invocar a função só com inteiros ou só com floats (por exemplo), correcto? nesse caso, não posso fazer o mesmo que fiz sem usar isso do 'Eq a =>', é que também ainda não dei isso e não sei se é suposto usar-mos lol... mas também, só são fichas...

quanto ao '[a] -> a -> Bool' em vez de '([a], a) -> Bool', só o fiz assim porque achei que ficava mais giro lol... mas hs grande diferença entre ambas ou é porque a primeira é + fácil de usar e pode dar menos dores de cabeça?

Link to comment
Share on other sites

se ainda não falaste no 'Eq a' então também não deve ser suposto fazeres funções para tipos "variáveis"... podias sempre retirar a assinatura da função e já não usavas o 'Eq a'.

quanto ao segundo ponto, não é que te vá dar dores de cabeça, mas em disciplinas mais avançadas de Haskell os profs gostam que tu uses programação pointfree (sem variáveis), o que é mais simples quando separamos os argumentos. mas provavelmente para já isso não é relevante.

Link to comment
Share on other sites

É a chamada programação em Lógica 😄

Para quem tá habituada a linguagens como C, Java etc... Programação em logica é realmente assustador mas depois de se perceber o funcionamento é sempre a andar.

Eu ja fiz um cadeira de Haskell e tou agora a fazer uma de Prolog que tambem é como haskell mas mais complicada.

I haven’t lost my mind; it’s backed up on DVD somewhere!

Link to comment
Share on other sites

É a chamada programação em Lógica 😄

[...]

Eu ja fiz um cadeira de Haskell e tou agora a fazer uma de Prolog que tambem é como haskell mas mais complicada.

eu diria mais programação funcional.

quanto ao Prolog ser mais complicado, isso é muito relativo, quando começamos a meter monads, catamorfismos, e outras coisas mais avançadas o Haskell já não é assim tão simples... eu achei o Prolog mais simples, mas também não aprofundei tanto o Prolog como o Haskell (que é a linguagem que mais usei até agora no curso).


(...)fazeres funções para tipos "variáveis"(...)

Isto significa o quê mesmo? Ainda tou muito verde em haskell...

E como é que é possível programar sem usar variáveis?  ?

quando me referi a fazer funções para tipos variáveis referia-me a funções do tipo "a -> b" (em vez de "Int -> Bool", por exemplo) pois os valores que o 'a' e o 'b' podem assumir são "variáveis".

quanto às funções sem variáveis:

--soma de todos os elementos de uma lista
sum :: Int -> Int
sum = foldr (+) 0

--subconjuntos de um conjunto (lista)
sub :: [a] -> [[a]]
sub =foldr (\x r -> (map (x:) r) ++ r) [[]]

na função 'sum' não encontras variáveis (apesar de ser uma função que recebe uma lista).

na função 'sub' que também recebe uma lista, não tens variáveis antes do '='. no entanto esta já tem variáveis na definição da função que o 'foldr' recebe, por isso não é totalmente pointfree (para que não tivesse nenhuma variável teria que complicar bastante a função...).

em Haskell é possível programar muita coisa sem recorrer a variáveis, mas quando se leva isto ao extremo, deixamos de perceber as funções.

Link to comment
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
 Share

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