From 13c24c82f047d9413e8fc73b5190d2a40d69b127 Mon Sep 17 00:00:00 2001 From: Aldwin Vlasblom Date: Sat, 24 Apr 2021 12:01:17 +0200 Subject: [PATCH] Update the equals function to fall back to structural equality When comparing two values that are: 1. of the same type; and 2. do not provide a 'fantasy-land/equals'-method; but 3. also don't have a known type with a Z-provided implementation, then previously Z.equals would return false, but this false is just as reliable as a true would be. After this commit, instead of returning false, the Z.equals now returns the structural equality of the two inputs. --- index.js | 20 ++++++++++++-------- test/index.js | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 6c818fc..ba14b06 100644 --- a/index.js +++ b/index.js @@ -1113,12 +1113,16 @@ //# equals :: (a, b) -> Boolean //. - //. Returns `true` if its arguments are of the same type and equal according - //. to the type's [`fantasy-land/equals`][] method; `false` otherwise. + //. Returns `true` if the two arguments given are structurally equal. When + //. comparing two values, equality is determined based on: //. - //. `fantasy-land/equals` implementations are provided for the following - //. built-in types: Null, Undefined, Boolean, Number, Date, RegExp, String, - //. Array, Arguments, Error, Object, and Function. + //. - The types of the two values. Values of differing types unequal. + //. - The [`fantasy-land/equals`][] method of the first value when present. + //. - For Null, Undefined, Boolean, Number, Date, RegExp, String, Array, + //. Arguments, Error, Object, and Function, Sanctuary Type Classes provides + //. `fantasy-land/equals` implementations. + //. - Any other types are structurally compared by recursively comparing the + //. values at each of the keys. //. //. The algorithm supports circular data structures. Two arrays are equal //. if they have the same index paths and for each path have equal values. @@ -1154,9 +1158,9 @@ $pairs.push ([x, y]); try { - return Z.Setoid.test (x) && - Z.Setoid.test (y) && - Z.Setoid.methods.equals (x) (y); + return Z.Setoid.test (x) ? + Z.Setoid.methods.equals (x) (y) : + Object$prototype$equals.call (x, y); } finally { $pairs.pop (); } diff --git a/test/index.js b/test/index.js index 21f7a6a..2059592 100644 --- a/test/index.js +++ b/test/index.js @@ -673,7 +673,7 @@ test ('equals', () => { eq (Z.equals (Math.sin, Math.cos), false); eq (Z.equals (Identity (Identity (Identity (0))), Identity (Identity (Identity (0)))), true); eq (Z.equals (Identity (Identity (Identity (0))), Identity (Identity (Identity (1)))), false); - eq (Z.equals (Useless, Useless), false); + eq (Z.equals (Useless, Useless), true); eq (Z.equals (Array.prototype, Array.prototype), true); eq (Z.equals (Nothing.constructor, Maybe), true); eq (Z.equals ((Just (0)).constructor, Maybe), true);