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