开发者

Haskell: Stuck writing a function to replicate`elem`

For my very first lecture in haskell we where given a series of problems. One of them is to return True when n number is present in a list, or False otherwise. I managed to get what i think is half-way there but am getting different compile errors and am pretty frustated because I can even understand what they mean.

So far I have done the following

// No problem with this function
matches :: Int -> [Int] -> [Int]    // This function is to return the matches 
matches x y = [a | a <-y, a==x]     // ie. main> 1 [1,3,5,7,1,4] outputs [1,1]

// Here am stuck
myelem :: Int -> [Int] -> Bool
myelem x [] = False
myelem x (y:ys)
 | x == y = y : x myelem ys       // Am not sure about recursion as 
                                  // we have not yet covered

Obviously this is for a class so please do not post the answer. But maybe a few examples that will help me reason about both the workings of Has开发者_JAVA技巧kell and how to approach the problem. Any pointer will be massively appreciated.


SOLUTION

matches :: Int -> [Int] -> [Int]
matches x y = [a | a <-y, a==x]

myelem :: Int -> [Int] -> Bool
myelem x [] = False
myelem x (y:ys)
 | x == y = True
 | otherwise = myelem x (ys)

Cheers guys


The problem is in your last equation:

myelem x (y:ys)
 | x == y = y : x myelem ys

There are two problems here:

  1. If you want to use myelem as an infix operator, you have to surround it in backticks, like so:

    x `myelem` ys
    
  2. Given that's what you meant, the right hand side of your equation doesn't type check; the list constructor (:) requires its second argument to be a list, not a Bool. Furthermore, (:) constructs a list, and myelem is supposed to return a Bool!

Think about what you're trying to do. If x == y, you just want to return True, right? And otherwise, you want to return the result of checking the rest of the list (ys). Hope that helps.


You are actually pretty close to the right answer. I see two main issues, though. One is that the call to myelem on the last line of code needs to have backquotes around it to make it infix (x `myelem` ys) or a prefix call without backquotes (myelem x ys). Also, you do not want to prepend y to the result of the recursive call. You actually do not need a condition on your second pattern: just think about what myelem x (y:ys) should return using simple Boolean operations and the recursive call you already have there.


You try to concat an Int and a Bool in the last line; think again.

You never return True from myelem; sometimes it is appropriate.

Once these issues are fixed, the code works.


You could also write your function using some combination of the following functions (there are at least two ways of doing it using the functions below):

filter :: (a -> Bool) -> [a] -> [a]

removes elements from a list unless they satisfy some set of criteria

null :: [a] -> Bool

returns whether the list is empty or not

not :: Bool -> Bool

is logical negation

or :: [Bool] -> Bool

returns True if a list of Bool contains one or more True values.

Obviously, you've solved your problem, but it might help you to explore other ways of doing the same thing.


Note that you could also define your myelem function in terms of matches.

  • What will matches return if the item is not in the list?
  • What will matches return if the item is in the list once? twice? many times?
  • Do you care about the entire return value in the second case? (hint: no)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜