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

Nazgulled

[Haskell] Verificar se um elemento está numa lista

8 mensagens neste tópico

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
(...)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?  :eek:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É a chamada programação em Lógica :D

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É a chamada programação em Lógica :D

[...]

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?  :eek:

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois eu de haskell tambem só tive uma cadeira dei bazicamente o basico, até lista strings essas coisas, prolog quando começa a meter arvores e coisinhas assim a coisa complica :D

0

Partilhar esta mensagem


Link 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