txt: ## eqv.md
  eqv
  
  Combined from primary sources listed below.
  
  # [In Match](#___top "go to top of document")[§](#(Match)_infix_eqv "direct link")
  
  See primary documentation
  [in context](/type/Match#infix_eqv)
  for **infix eqv**.
  
  ```raku
  multi infix:<eqv>(Match:D \a, Match:D \b)
  ```
  
  Returns `True` if the attributes `pos`, `from` and `orig` for `a` and `b` are equal, and if `made`, `Capture::list` and `Capture::hash` are either the same or both undefined.
  
  # [In ObjAt](#___top "go to top of document")[§](#(ObjAt)_infix_eqv "direct link")
  
  See primary documentation
  [in context](/type/ObjAt#infix_eqv)
  for **infix eqv**.
  
  ```raku
  multi infix:<eqv>(ObjAt:D $a, ObjAt:D $b)
  ```
  
  Returns True if the two ObjAt are the same, that is, if the object they identify is the same.
  
  ```raku
  my @foo = [2,3,1];
  my @bar := @foo;
  say @foo.WHICH eqv @bar.WHICH; # OUTPUT: «True␤»
  ```
  
  # [In Operators](#___top "go to top of document")[§](#(Operators)_infix_eqv "direct link")
  
  See primary documentation
  [in context](/language/operators#infix_eqv)
  for **infix eqv**.
  
  ```raku
  sub infix:<eqv>(Any, Any)
  ```
  
  This could be called an equivalence operator, and it will return `True` if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values.
  
  ```raku
  say [1, 2, 3] eqv [1, 2, 3];    # OUTPUT: «True␤»
  say Any eqv Any;                # OUTPUT: «True␤»
  say 1 eqv 2;                    # OUTPUT: «False␤»
  say 1 eqv 1.0;                  # OUTPUT: «False␤»
  ```
  
  Lazy [`Iterable`](/type/Iterable)s cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return `False` if the two lazy [`Iterable`](/type/Iterable)s are of different types or if only one [`Iterable`](/type/Iterable) is lazy.
  
  ```raku
  say (1…∞) eqv (1…∞).List; # Both lazy, but different types;   OUTPUT: «False␤»
  say (1…∞) eqv (1…3);      # 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␤»
  ```
  
  In some cases, it will be able to compare lazy operands, as long as they can be iterated
  
  ```raku
  my $a = lazy ^2;
  my $b = $a;
  $a.cache;
  say $a eqv $b; # OUTPUT: «True␤»
  
  ```
  
  When cached, the two lazy [`Seq`](/type/Seq)s can be iterated over, and thus compared.
  
  The default `eqv` operator even works with arbitrary objects. E.g., `eqv` will consider two instances of the same object as being structurally equivalent:
  
  ```raku
  my class A {
      has $.a;
  }
  say A.new(a => 5) eqv A.new(a => 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:
  
  ```raku
  my class A {
      has $.a;
  }
  multi infix:<eqv>(A $l, A $r) { $l.a eqv $r.a }
  say A.new(a => 5) eqv A.new(a => 5);            # OUTPUT: «True␤»
  ```
  
  Note that `eqv` does not work recursively on every kind of container type, e.g. [`Set`](/type/Set):
  
  ```raku
  my class A {
      has $.a;
  }
  say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «False␤»
  ```
  
  Even though the contents of the two sets are `eqv`, the sets are not. The reason is that `eqv` delegates the equality check to the [`Set`](/type/Set) object which relies on element-wise `===` comparison. Turning the class `A` into a value type ([`ValueObjAt`](/type/ValueObjAt)) by giving it a `WHICH` method produces the expected behavior:
  
  ```raku
  my class A {
      has $.a;
      method WHICH {
          ValueObjAt.new: "A|$!a.WHICH()"
      }
  }
  say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «True␤»
  ```
  
  You can call a single-argument version of the operator by using its full name; it will always return true.
  
  ```raku
  say infix:<eqv>(33);    # OUTPUT: «True␤»
  say infix:<eqv>(False); # OUTPUT: «True␤»
  
  ```
  
  # [In Allomorph](#___top "go to top of document")[§](#(Allomorph)_infix_eqv "direct link")
  
  See primary documentation
  [in context](/type/Allomorph#infix_eqv)
  for **infix eqv**.
  
  ```raku
  multi infix:<eqv>(Allomorph:D $a, Allomorph:D $b --> Bool:D)
  ```
  
  Returns `True` if the two `Allomorph` `$a` and `$b` are of the same type, their [`Numeric`](/type/Numeric) values are [equivalent](/routine/eqv) and their [`Str`](/type/Str) values are also [equivalent](/routine/eqv). Returns `False` otherwise.
  