Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing a string from a list of strings in Haskell

Tags:

string

haskell

I have a question regarding Haskell that's been stumping my brain. I'm currently required to write a function that removes a string i.e. "word" from a list of strings ["hi", "today", "word", "Word", "WORD"] returns the list ["hi", "today", "Word", "WORD"]. I cannot use any higher-order functions and can only resort to primitive recursion.

Thinking about the problem, I thought maybe I could solve it by using a recursion where you search the head of the first string, if it matches "w" then compare the next head from the tail, and see if that matches "o". But then I soon realized that after all that work, you wouldn't be able to delete the complete string "word".

My question really being how do I compare a whole string in a list rather than only comparing 1 element at a time with something like: removeWord (x:xs). Is it even possible? Do I have to write a helper function to aid in the solution?

like image 713
Phirip Avatar asked May 12 '13 00:05

Phirip


3 Answers

Consider the base case: removing a word from an empty list will be the empty list. This can be trivially written like so:

removeWord [] _ = []

Now consider the case where the list is not empty. You match this with x:xs. You can use a guard to select between these two conditions:

  1. x is the word you want to remove. (x == word)
  2. x is not the word you want to remove. (otherwise)
like image 137
icktoofay Avatar answered Nov 05 '22 11:11

icktoofay


You don't need a helper function, though you could write one if you wanted to. You've basically got 3 conditions:

  1. You get an empty list.
  2. You get a list whose first element is the one you want to remove.
  3. You get a list whose first element is anything else.

In other languages, you would do this with a set of if-else statements, or with a case statement, or a cond. In Haskell, you can do this with guards:

remove_word_recursive:: String -> [String] -> [String]
remove_word_recursive _ []                              = []
remove_word_recursive test_word (x:xs) | test_word == x = what in this case?
remove_word_recursive test_word (x:xs)                  = what in default case?

Fill in the correct result for this function in these two conditions, and you should be done.

I think what you're looking for is a special case of the function sought for this question on string filters: Haskell - filter string list based on some conditions . Reading some of the discussion on the accepted answer might help you understand more of Haskell.

like image 42
pcurry Avatar answered Nov 05 '22 11:11

pcurry


Since you want to remove a list element, it's easy to do it with List Comprehension.

myList = ["hi", "today", "word", "Word", "WORD"]
[x | x <- myList, x /= "word"]

The result is:

["hi","today","Word","WORD"]
like image 39
Mark Avatar answered Nov 05 '22 12:11

Mark