title: List matching in OCaml
body: <p>I have a function that I'm working on in Ocaml. It consists of a function that takes in two string lists and returns a string list. The function operates as follows. It scans each individual string in the first list and if it finds a corresponding match in the second list, it returns that match. If the second list has a duplicate match, the match would return twice. Here are test cases I've written that describe the expected behavior:</p>
  
  <pre><code>let test () : bool =
    (in_both [] ["Pearl"; "Steven"]) = []
  ;; run_test "in_both empty name list 1" test
  
  let test () : bool =
    (in_both ["Pearl"; "Steven"] []) = []
  ;; run_test "in_both empty name list 2" test
  
  let test () : bool =
    (in_both ["Pearl"; "Amethyst"; "Henry"] ["Pearl"; "Steven"]) = ["Pearl"]
  ;; run_test "in_both one repeat in both lists" test
  
  let test () : bool =
    (in_both ["Pearl"; "Amethyst"; "Gary"; "Blair"] ["Pearl"; "Amethyst"; "Blair"]) 
    = ["Pearl";"Amethyst";"Blair"]
  ;; run_test "in_both three different repeats in both lists" test
  
  let test () : bool =
    (in_both ["Garnet"; "Amethyst"; "Pearl"] ["Pearl"; "Pearl"]) 
    = ["Pearl";"Pearl"]
  ;; run_test "in_both two repeat in second list" test
  </code></pre>
  
  <p>Here is my function implementation:</p>
  
  <pre><code>let rec in_both (names1: string list) (names2: string list) : string list =
    begin match (names1, names2) with
    |([],[])-&gt; []
    |([],hd2::tl2)-&gt; []
    |(hd1::tl1,[])-&gt; []
    |(hd1::tl1,hd2::tl2)-&gt;if contains_str names2 hd1 = true then hd1::in_both tl1 
    tl2 else in_both tl1 names2
    end
  </code></pre>
  
  <p>All of my tests pass except the last test, where it looks like <code>"Pearl"</code> does not print out twice when it should. What could I be doing wrong in my implementation? For reference, here is the function definition for the contains_str function that I called in in_both:</p>
  
  <pre><code>let rec contains_str (l: string list) (name: string) : bool =
    begin match l with
    |[]-&gt; false
    |hd::tl-&gt; hd = name || contains_str tl name
    end
  </code></pre>
  
  <p>Any help is appreciated!</p>