Can you introspect predicate arity and if it's an equality predicate?

Simen Kjærås simen.kjaras at gmail.com
Fri Jan 12 08:18:02 UTC 2018


On Friday, 12 January 2018 at 00:16:07 UTC, aliak wrote:
> Hi, so basically is there a way to:
>
> void func(alias pred = null, Range)(Range range) {
>   // 1) check if pred(ElementType!Range.init, 
> ElementType!Range.init) is equality
>   // 2) check if isUnary!pred
>   // 3) check if isBinary!pred
> }

For 2 and 3, there's std.traits.arity. However, as you point out, 
it has some problems with templated functions. This template will 
handle those cases in conjunction with std.traits.arity:

import std.traits : arity, isCallable;

template arity(alias Fn, Args...)
if (is(typeof(Fn!Args)) && isCallable!(typeof(Fn!Args)))
{
     enum arity = .arity!(Fn!Args);
}

unittest {
     assert(arity!(() => 1) == 0);
     assert(arity!(a => a, int) == 1);
     assert(arity!((a,b) => a, int, float) == 2);

     void test(T)(T,T,T) {}
     assert(arity!(test, int) == 3);
}

Checking if a function is the equality function is much harder. 
Consider this function:

bool compare(int a, int b) {
     if (a == 2 && b = 3) return true;
     return a == b;
}

Clearly this is not an equality function, but for the vast 
majority of inputs, it behaves exactly the same.

There are other examples that make this hard. It's perfectly 
possible to overload opEquals and have it ignore some fields, or 
even access a database on the other side of the atlantic ocean. 
In these cases, evaluating the equality of two objects is not 
testable at compile time, and you simply cannot know.

In your examples you use string functions ("a == b", e.g.). These 
can of course be compared (you might want to do some processing, 
as "a==b" should give the same result as "b        ==      a"). 
There's cases here where you can't be sure, of course.

All in all, I believe you're trying to solve the wrong problem, 
but I might be wrong. Care to give a bit more information so I 
get a better idea of why you want to do this?

--
   Simen


More information about the Digitalmars-d-learn mailing list