Search code examples
visual-studiohaskellghci

Removing the first instance of an element (Haskell)


I am new to working with haskell but I tried to follow the answer to this question to create my own function that takes a list and an element as input and removes the first instance of said element from list.

My code looks like this:

rem1 :: Eq a => [a] -> a -> [a]
rem1 [] _ = []
rem1 ys _ = ys
rem1 (y:ys) x   | x == y    = ys
                | otherwise = y : rem1 ys x

The code compiles when I load it in ghci, but when I test it the list is unchanged. Like so:

Ok, one module loaded.
ghci> rem1 "abab" 'b'
"abab"

When it should be like this:

Ok, one module loaded.
ghci> rem1 "abab" 'b'
"aab"

How do I fix this?


Solution

  • For any argument except an empty list, the second case always fires:

    rem1 ys _ = ys
    

    It says "whatever the arguments are, always return the first argument". So it does.

    You were probably thinking about the second case "in comparison" with the third case: the third case matches on (:), and the second case matches "when there is no (:)".

    But that's not how pattern matching works. A pattern like ys matches anything, anything at all, regardless of whether it's the (:) constructor or not. So your second case matches any parameter.

    To fix, just remove the second case. You don't need it.