The most direct way to fix your code is to write something like the code below.
In the mem function, I just fixed the indentation and changed it to use head and tail , which you got from the pattern matching, and not to access them through list.Head and list.Tail (because it's more idiomatic and safe):
let rec mem list x = match list with | [] -> false | head :: tail -> if x = head then true else mem tail x
In intersection trick is to use head::rest to build the resulting list, when head is the element that appears in both lists (and rest is the list you get by applying the intersection to the tail recursively). You also do not need to match list2 , because mem handles empty lists perfectly:
let rec intersection list1 list2 = match list1 with | head :: tail -> let rest = intersection tail list2 if mem list2 head then head::rest else rest | [] -> []
This is not super efficient (assuming n is the length of list1 and m is the length of list2 , you may need up to m * n steps), but this is probably not the case. In addition, intersection not tail recursive, so it wonβt work on large lists, but this is another - more advanced - functional programming issue.
Finally, the code will also return a list that may contain one element several times - but I think this is good for you (for example, intersection [1;1;1] [1] returns [1;1;1] , but if you flip the arguments, you only get [1] )
source share