Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell isMember function error

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

Trying to create a function that will identify whether something is a member of a list. For example:

isMember 6 [1,2,3,4,5,6]
>True

However I keep getting a complier error stating 'no instance for (Eq a) arising from the use of '=='

Help would be appreciated (I'm new to Haskell & Recursion in functional languages so explain like I'm five.)

like image 617
Kieran Atkins Avatar asked Oct 26 '17 19:10

Kieran Atkins


1 Answers

you are almost there

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

What the compiler tells you that you promised to accept any type of list members - but later you use the function == which is not available for all types (for example functions).

By adding Eq a => you say I accept all input which have an equals method.

Some additional notes

You can (re)write the last line as

isMember y (x:xs) = (y == x) || isMember y xs

which is equivalent to your implementation (thanks @chi for the comment). What is nice about your version is that it is tail recursive.

Another point to note - the pattern:

  • return something for empty list case (isMember _ [] = False)
  • and iterate over the list with this value (isMember y (x:xs) = ...)

happens to turn up a lot and has been abstracted into the family of fold -functions (foldl, foldr ...). Putting it in your use case it looks like

isMember y xs = foldl False (\x b -> (x == y) || b) xs
like image 120
epsilonhalbe Avatar answered Nov 07 '22 07:11

epsilonhalbe