The fact that arrays are used in the type definition is unrelated. The issue comes from the fact that your match function’s type is (e<'a>, e<'b>) => bool, so the typechecker infers that root and target both contain e<'a> types. Then when you try to pass a value of type t<intObj> instead of t<e<'a>, it creates the error.
Records are not structurally typed, so you can’t have a function that takes “any record with an id field” as an argument.
There are several ways you can solve this. One simple solution is to just use a different match function for the intObj type. Example.
Any function can either work on e<'i> or 'i, but not both. Fundamentally, you need two functions, one for each type.
You don’t necessarily need to use a functor. If you can’t statically define the match_intobj function (like in my last example), then you can instead provide it as an argument for your deleteItem function. See this example.