On Mon, 20 Jul 2020 12:37:33 +0200
Theo van den Heuvel <vdheu...@heuvelhlt.nl> 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

Reply via email to