I am not the right person to answer that question with authority but basically == is implemented via multiple dispatch for different types.
e.g.
julia> typeof(probit1)
StatsModels.TableRegressionModel{GeneralizedLinearModel{GLM.GlmResp{Array{Float64,1},Binomial{Float64},ProbitLink},GLM.DensePredChol{Float64,Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}
so it is not clear what it does exactly for this type. One would have to check the source of the GLM package if that defines a specific ==. There is a fallback I think:
from the docs:
help?> isequal
search: isequal issetequal InverseSquareLink
isequal(x, y)
Similar to ==, except for the treatment of floating point numbers and of missing values. isequal treats all floating-point NaN values as equal to each other, treats -0.0 as
unequal to 0.0, and missing as equal to missing. Always returns a Bool value.
Implementation
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
The default implementation of isequal calls ==, so a type that does not involve floating-point values generally only needs to define ==.
isequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).
This typically means that types for which a custom == or isequal method exists must implement a corresponding hash method (and vice versa). Collections typically implement isequal
by calling isequal recursively on all contents.
Scalar types generally do not need to implement isequal separate from ==, unless they represent floating-point numbers amenable to a more efficient implementation than that
provided as a generic fallback (based on isnan, signbit, and ==).
EDIT:
Looks like the fallback is called which would not work I guess
julia> @which isequal(probit1, probit2)
isequal(x, y) in Base at operators.jl:123