Home > Raku > Inequality

## Inequality

As stated before, I like to read code I didn’t write myself. Flavio had trouble with triples. One line stood out to me.

``take @triple if \$N == @triple.any;``

This looks like a set-operation to me. But using `\$N ∈ @triple` dropped one result. After some debugging I found the culprit.

``.map({(\$_, \$n / \$_)});  # take it and its counterpart``

This might look like a division but is actually a type cast to `Rat`.

``````say 1 ∈ (1/1, );
# OUTPUT: False``````

Rakudo implements set-operations as equivalence checks, not numerical equality. Quite in contrast to `==`, `eqv` does a type check and `Int` aint’t `Rat`. This might explain that the mathematical inclined don’t use `Set` as much as I did expect them to. The type mismatch simply produces a result that is not useful to mathematicians.

As implemented right now, we can’t tell the set operators what we consider equality . With meta-operators and junctions, we can specify what operator we actually want to use. The set-operators are not meta-operators and at least for now, we can’t user define new meta-operators. However, we can lexically redefine ordinary operators.

``````proto sub infix:<(elem)>(\$, \$, *% --> Bool:D) is pure {*}
multi sub infix:<(elem)>(Numeric:D \a, Iterable:D \listy --> Bool:D) {
Any.fail-iterator-cannot-be-lazy('∈', '') if listy.is-lazy;

for listy -> \b {
return True if a == b;
}

False
}

constant &infix:<∈> := &infix:<(elem)>;

proto sub infix:<(&)>(|) is pure {*}
multi sub infix:<(&)>(Iterable:D \lhs, Iterable:D \rhs) {
Any.fail-iterator-cannot-be-lazy('∩', '') if lhs.is-lazy || rhs.is-lazy;

my @result;

for lhs -> \l {
for rhs -> \r {
@result.push: r if l == r;
}
}

+@result ?? @result !! ∅
}

constant &infix:<∩> := &infix:<(&)>;

say 1 ∈ (1/1, );
say (42, 42/2, 42/3) ∩ (1, 21, 3);
# OUTPUT: True
#         Set(21)``````

The `proto` is needed, because we need to get rid of multi-candidates that are already present. A more general approach might be to have a `&*SET-COMPARATOR` that defaults to `&infix:<cmp>`. This would slow down a fairly simple operator by a factor of 13. I may still be able to write a module that takes a comparator and returns a host of operators. With proper macros this would be easy. Maybe next year.

For now I shall be evil and report back with success.

Categories: Raku
1. No comments yet.
1. August 16, 2021 at 16:08
2. August 23, 2021 at 14:26