On Mon, 20 Jul 2020 12:37:33 +0200
Theo van den Heuvel <[email protected]> wrote:
> The situation: I have a function, let's call in 'walker', whose first
> parameter is a callback.
> I wish to express that only callbacks with a certain Signature and
> return type are acceptable.
> Let's say the callback should follow :(Numeric $n --> Numeric). My
> callback is going to be more complicated, but for simplicity sake.
Interesting problem!
I tried::
use v6.d;
subset Walkable of Callable where { $^c.signature ~~ :(Numeric $--> Numeric)
};
sub walker(Walkable &callback) {
say callback(1);
}
sub callback(Numeric $x --> Numeric) { 1+$x }
say 'is Callable? ', &callback ~~ Callable;
say 'does the signature match? ', &callback.signature ~~ :(Numeric $n -->
Numeric);
say 'is Walkable? ', &callback ~~ Walkable;
walker(&callback);
which prints::
is Callable? True
does the signature match? True
is Walkable? True
Type check failed in binding to parameter '&callback'; expected Walkable but
got Sub+{Callable[Numeric]} (sub callback (Numeric...)
in sub walker at /tmp/s.raku line 5
in block <unit> at /tmp/s.raku line 15
which is quite surprising to me.
Aside:
``(sub (Int $ --> Int) {}) ~~ Walkable`` is false, because
``:(Int $ --> Int) ~~ :(Numeric $ --> Numeric)`` is false, which is
correct because function subtypes should be contravariant in the parameter
types and covariant in the return type (i.e. if the caller passes a
Numeric, the callback should accept a Numeric or a *more general*
type, and if the caller expects a Numeric back, the callback should
return a Numeric or a *more specific* type).
But then ``:(Numeric $ --> Int) ~~ :(Numeric $ --> Numeric)`` is also
false, and I feel like it should be true. Opinions?
--
Dakkar - <Mobilis in mobile>
GPG public key fingerprint = A071 E618 DD2C 5901 9574
6FE2 40EA 9883 7519 3F88
key id = 0x75193F88