问题
I´m trying to write a function that produces a new list containing the given list without the element x.
Moscow ML says that some cases are unused in this match.
fun delete (x,list) = delete(x,[])
|delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
回答1:
Here's how I'd do it on Standard ML::
fun delete (item, list) =
case list of
[]=>[]
| xs::ys => if item = xs then delete(item,ys)
else xs::delete(item,ys)
Without using cases:
fun delete (item, list) = List.filter(fn x => x <> item) list
Nevermind the polyequal signs.
回答2:
When a call to delete
is performed, the patterns defining the function are (essentially) tried in order. Since the first pattern already matches every list, the second pattern will never be reached. That's why the compiler complains.
In other words, you either have to reorder your cases, or better, make them disjoint (e.g. by replacing list
with []
in the first case).
Extra hint: The right-hand side of the first case also seems wrong. This will always go into an infinite recursion.
回答3:
That's because your first case matches any list, so the second case will never be used.
Remember that the case are tried in the order they're written, not selected based on which is the "best" match.
You also have a slight problem of infinite recursion with
delete (x,list) = delete(x,[])
Since list
will match []
, it will just recurse forever.
If you delete something from an empty list, the result should be the empty list.
You can do one of two things.
Either move the non-empty case first:
fun delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
| delete (x, list) = []
Or, more common, make the first case only match the empty list:
fun delete (x, []) = []
| delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
来源:https://stackoverflow.com/questions/18291683/remove-elements-from-a-list-in-ml