So that makes sense, there’s no custom equality comparer for tuples, and since the references are different the obj equals fails. But why do the other things Richard said hold true then?

Well arrays have their own custom comparer that compares contents, that much is visible in the NUnit source. And tuples look to generate the same hash code IF they have value types in them, which you can test in fsi.

Suddenly they aren’t equal! Arrays, being a built in .NET primitive, follow these semantics for generating a hash code. Basically, they return a different value per each instance of the object in the app domain.

Now why does the f# = operator work? From the source, it looks like they have created custom comparators for f# types which does structural equality: