let compare_substring (a, idxa, lena) (b, idxb, lenb) =     let module With_exns = struct       exception Left       exception Right       let rec drop_until ~exn idx l =         match idx, l with         | 0, l -> l         | more, [] -> raise exn         | more, h :: t -> drop_until ~exn (more - 1) t       let f () =         begin try           let rec cmp l1 l2 len1 len2 =             if len1 < 0 then raise Left;             if len2 < 0 then raise Right;             match l1, l2 with             | _, _ when len1 = 0 && len2 = 0 -> 0             | _, _ when len1 = 0 -> -1             | _, _ when len2 = 0 -> 1             | [], [] when len1 = 0 || len2 = 0 -> Pervasives.compare lena lenb             | [], _ when len1 > 0 -> raise Left             | _, [] when len2 > 0 -> raise Right             | h1 :: t1, h2 :: t2 when Char.compare h1 h2 = 0 ->               cmp t1 t2 (len1 - 1) (len2 - 1)             | h1 :: _, h2 :: _ -> Char.compare h1 h2             | _, _ -> assert false (* calming down the warnings.. *)           in           if lena = 0 && lenb = 0 then 0           else (             let aa = drop_until ~exn:Left idxa a in             let bb = drop_until ~exn:Right idxb b in             (cmp aa bb lena lenb)           )         with         | Left -> -1         | Right -> 1         | Failure s -> 1           (* dbg "(%d, %d/%d) Vs (%d, %d/%d) %s" idxa lena (length a) idxb lenb (length b) s; *)         end     end in     With_exns.f ()