0

This is confusing but working code. I just want some help in understanding why k::ks is taken as a'list list list and not a'list list. I want to take a list and a list of lists and check whether the first list is necessary. By necessary I mean, whether all of the elements on first list can be found in another.

fun do1(a,[],_)=false
|do1(a,k::ks,n)=if a=List.nth(k,n)orelse do1(a,ks,n) then true else false;

val n=0;
fun do2([],k::ks,_)=[]
|do2(_,[],_)=raise unexpected
|do2(l,k::ks,n)=if List.nth(l,n-1)=0 then do2(l,k::ks,n+1)
                        else 
                        if do1(l,k::ks,n) then []
                        else l;

Question Repeated: I just want some help in understanding why k::ks is taken as a'list list list and not a'list list.

Thank You.

Mat
  • 202,337
  • 40
  • 393
  • 406

2 Answers2

0

In the definition of do2, l is a list. do2 then calls do1 with l as the first argument, so the first parameter of do1, a, is also a list. Now on line 2, you do a = List.nth(k,n). So since a is a list, List.nth(k,n) must also be a list. This means that k must be a list of lists. And that in turn means that k::ks must be a list of lists of lists.

PS: Generally when trying to find out why the compiler infers a different type than expected, it helps to add type annotations to your function definitions. Often the resulting type errors will give you a much clearer idea of where the compiler's opinion of the types involved starts to differ from yours.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
0

Though this type of codes do not really exchange ideas, I however have included the solution.

In the function,

fun do2([],k::ks,_)=[]
|do2(_,[],_)=raise unexpected
|do2(l,k::ks,n)=if List.nth(l,n-1)=0 then do2(l,k::ks,n+1)
                        else 
                        if do1(l,k::ks,n) then []
                        else l;

the second last line

if do1(l,k::ks,n) then []

should be

if do1(List.nth(l,n-1),k::ks,n) then []