Since [1, "foo"] is a valid list and _==_ is defined on lists, [1, "foo"] == ["foo", 1] should evaluate to false. It would be least surprising if list equality was determined by elementwise equality. Equivalently, [x] == [y] should have the same meaning as x == y. Therefore, _==_ should have signature A x B --> bool.
Similarly, _!=_ should work on heterogeneous types.
Restricting equality to homogeneous types was meant to prevent user errors. After all, heterogeneously 1 == 1u evaluates surprisingly to false. However the type checker can work with a stricter A x A --> bool signature for equality, catching these errors.
We might want to make heterogeneous order operators (_<_ and friends) too. We'll want an ordering across all values for deterministic map comprehensions, so why not expose it to users? The surprising consequences (e.g. if int < uint, then 1u < 2) can again be mitigated by having the type checker work heterogeneously.
Since
[1, "foo"]is a valid list and_==_is defined on lists,[1, "foo"] == ["foo", 1]should evaluate tofalse. It would be least surprising if list equality was determined by elementwise equality. Equivalently,[x] == [y]should have the same meaning asx == y. Therefore,_==_should have signatureA x B --> bool.Similarly,
_!=_should work on heterogeneous types.Restricting equality to homogeneous types was meant to prevent user errors. After all, heterogeneously
1 == 1uevaluates surprisingly tofalse. However the type checker can work with a stricterA x A --> boolsignature for equality, catching these errors.We might want to make heterogeneous order operators (
_<_and friends) too. We'll want an ordering across all values for deterministic map comprehensions, so why not expose it to users? The surprising consequences (e.g. if int < uint, then 1u < 2) can again be mitigated by having the type checker work heterogeneously.