I have to write this in sml/nj I made a try and this is what I did:
I want the all function to return a positive number when I run the function but for example when I give [1,2,3] [1,1,2,3,1,2,3,1]
it
returns nonexhaustive match failure.
What is wrong with the function and what can I do to see if the elements
of the first list exist in the second?
fun elem num [] = false
| elem num (x::xs) = if num = x then true else elem num xs
fun all [] [] =
let
fun qwe [] [] acc = acc
| qwe (x::xs) (z::zs) acc = if elem x (z::zs) then qwe xs (z::zs) (1+acc) else qwe xs (z::zs) acc
in
qwe [] [] 0
end
In your definition of all
, you seem to be slipping into thinking of []
as being a generic list rather than an empty list.
The only pattern that actually appears in your definition of all
is [] []
(two empty lists). That is most emphatically a case of nonexhaustive matching.
Since the helper function qwe
does the actual work, there really isn't any point in having pattern-matching on all
itself. The overall form of all
could be:
fun all xs ys =
let
fun qwe = (*insert definition*)
in
qwe xs ys 0
end;
(using zs
rather than ys
here looks a bit awkward)
The definition of que
should have 2-4 patterns. A 4-pattern definition (required for some functions which operate on two lists would be):
fun qwe [] [] acc = (*insert def*)
| qwe [] (y::ys) acc = (*insert def*)
| qwe (x::xs) [] acc = (*insert def*)
| qwe (x::xs) (y::ys) acc = (*insert def*)
This last gives 4 cases, one for each Boolean combination of the first list and the second list being empty. Sometimes you don't need to write separate code for each of those. For example,
fun qwe [] [] acc = (*insert def*)
| qwe [] ys acc = (*insert def*)
| qwe (x::xs) ys acc = (*insert def*)
combines the 3rd and 4th case into a single case.
If you look at your actual definition of elem
, you realize that it handles the case of empty ys
nicely, so in your definition of qwe
, you can really just have two patterns based on what xs
is doing:
fun qwe [] ys acc = (*insert def*)
| qwe (x::xs) ys acc = (*insert def*)
Since ys
can match both empty and nonempty lists, the above template is exhaustive.
With the appropriate definitions (which you essentially already have) for the above two cases of que
, your function all
will work:
- all [1,2,3] [1,1,2,3,1,2,3,1];
val it = 3 : int