how to compare an item in a Haskell list

5

I was trying to make a function that compares a given item with a list and if the item is on the list it returns a Boolean.

when compiling it, it throws this error at me and I do not understand what it refers to. I would appreciate your help ...

  Occurs check: cannot construct the infinite type: a ~ [a]
  • In the second argument of ‘(/=)’, namely ‘xs’
  In the second argument of ‘(&&)’, namely ‘n /= xs’
  In the expression: n /= x && n /= xs
• Relevant bindings include
    n :: a (bound at Listas.hs:22:17)
    xs :: [a] (bound at Listas.hs:22:13)
    x :: a (bound at Listas.hs:22:11)
    elemento :: [a] -> a -> Bool (bound at Listas.hs:21:1)
    |
 22 | elemento (x:xs) n = if n /= x && n /= xs then False else True

this is the code:

 elemento :: (Eq a) => [a] -> a -> Bool
 elemento [] a = error "no hay elementos en la lista"
 elemento (x:xs) n = if n /= x && n /= xs then False else True
    
asked by Pedro 14.09.2018 в 07:40
source

2 answers

1

Very good Pedro, I leave you an example of a search based on your code that should work:

elemento :: Eq a => [a] -> a -> Bool
elemento (x:xs) a = if a == x then True else elemento xs a
elemento [] a = False

I hope I can help you. Greetings

    
answered by 14.09.2018 в 08:34
1

The error is somewhat confusing. It tells you that can not build an infinite type . You may not understand it, but in the following lines it tells you that the problem is in n /= xs . You are comparing an element of type a with a list of elements of type a , which comes to define the type a as of recursive infinite type , something impossible to implement.

The correct way to do it would be using recursion :

elemento :: Eq a => [a] -> a -> Bool
elemento [] _ = False
elemento (x:xs) a | x == a    = True
                  | otherwise = elemento xs a

There are other modes, for example with list compression :

elemento :: Eq a => [a] -> a -> Bool
elemento xs a = or [x==a | x <- xs]

I guess you're starting with haskell. This type of check can be done directly with the elem function that is loaded in Prelude , so it is available directly. Only the arguments should be reversed:

elemento :: Eq a => [a] -> a -> Bool
elemento = flip elem
    
answered by 15.09.2018 в 01:11