The issue here is not per se the function itself, but the input list:
remove [ A "List", A "List", A "Gone", A "Still"]
It contains a list of elements, each element has the data constructor A followed by a string. In some languages like Prolog, one can dynamically introduce functors, but not in Haskell: Haskell is statically typed, and as a result you need to declare the types. We can for instance declare the type:
data A = A String deriving (Eq, Show)
Now we declared a type A, where there is a single data constructor A that takes as parameter a String. We made it deriving (Eq, Show), such that two As are equal, given they have the same data constructor (but since there is only one, this is always the case), as well as the fact that the parameter should be the same. The Show enables us to print A instances.
So now it will at least produce output (not generate a compiler error). But the function itself still has a potential problem: here you check membership in the tail of ther list. There can be two problems with that:
- we will always keep the last occurrence, so
remove [1, 4, 1, 2] will return [4, 1, 2], whereas we probably want to return [1, 4, 2]; and
- in case we process an infinite list, then for non-duplicate elements,
elem, will keep looking for a duplicate. As a result eventually Haskell will run out of memory and crash.
We better use an accumulator here that stores the elements thus far observed, and call elem on that list, like:
remove :: Eq a => [a] -> [a]
remove = go []
where go _ [] = []
go seen (x:xs) | elem x seen = go seen xs
| otherwise = x : go (x:seen) xs
Asupposed to be here? Of course the compiler doesn't know what you're talking about, ifAisn't defined!A, or remove it. I don't know what you want it to be, but you probably want this line:data A = A String deriving (Eq, Show).