I want to make the function remove :: String -> Char -> String
which removes all instances of the character in the second argument
from the string in the first argument. For example:
remove "ab cd ef" ' ' == "abcdef"
remove "ab cd cf" 'c' == "ab d f"
What I have so far is:
remove (x:xs) y
| x == y = xs
| otherwise = x : remove xs y
This only removes one element, e.g. if I write remove "ab cd ef" ' '
it prints out "abcd ef"
and not "abcdef"
.
I need to make one function using recursion and another one using list comprehension.
As chi pointed out in the comments, you need to use recursion in both branches or you'll end up only removing the first instance.
For completeness here is the correct code:
remove [] _ = []
remove (x:xs) y
| x == y = remove xs y
| otherwise = x : remove xs y
If you do not include the []
case then you will get an error about pattern matching -- this is because when you match the pattern (x:xs)
you are assuming that the array has length of >= 1 for x
to be defined. If you think of lists like data List a = Cons a (List a) | Empty
, then any functions that take a list must pattern match over the Cons
and the Empty
constructors. Obviously, if you have an empty string there's nothing to remove so []
maps to []
for all y
.
If you want list comprehension as well, recognise that list comprehension is map
and filter
combined. We don't want to change the characters which map
allows us to do, only to filter out the ones which match y
.
The syntax [f x | x <- xs, predicate x]
means "take every x
from xs
where the expression predicate x
is True
, and return a list of expressions f x
. The f x
is the map
part, the predicate x
is the filter part.
Thus we can write:
remove xs y = [x | x <- xs, x /= y]
Note here that we don't pattern match the list value constructors, so we don't need two cases. The x <- xs
part simply means we get []
if the input list is empty. We've also used x
or id x
instead of f x
, and our predicate is x /= y
.
Also FYI the template-haskell
tag isn't necessary here, that's a metaprogramming language extension.