Documentation for infix eqv

Documentation for infix eqv, assembled from the following types:

language documentation Operators

From Operators

(Operators) infix eqv

sub infix:<eqv>(AnyAny)

Equivalence operator. Returns True if the two arguments are structurally the same, i.e. from the same type and (recursively) contain the same values.

say [123eqv [123];    # OUTPUT: «True␤» 
say Any eqv Any;                # OUTPUT: «True␤» 
say 1 eqv 2;                    # OUTPUT: «False␤» 
say 1 eqv 1.0;                  # OUTPUT: «False␤» 

Lazy Iterables cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return False if the two lazy Iterables are of different types or if only one Iterable is lazy.

say (1…∞) eqv (1…∞).List# Both lazy, but different types;   OUTPUT: «False␤» 
say (1…∞) eqv (13);      # Same types, but only one is lazy; OUTPUT: «False␤» 
(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws. 
    orelse say $!.^name;  # OUTPUT: «X::Cannot::Lazy␤» 

The default eqv operator even works with arbitrary objects. E.g., eqv will consider two instances of the same object as being structurally equivalent:

my class A {
    has $.a;
say> 5eqv> 5);  # OUTPUT: «True␤» 

Although the above example works as intended the eqv code might fall back to a slower code path in order to do its job. One way to avoid this is to implement an appropriate infix eqv operator:

my class A {
    has $.a;
multi infix:<eqv>(A $lA $r{ $l.a eqv $r.a }
say> 5eqv> 5);            # OUTPUT: «True␤»