Type captures are a cool thing to use for even some simple stuff:
sub assert-same(::T $a, T $b) { ; }
assert-same 1, 2; # silent
assert-same 1, "a"; # type check error
However, the result is non-intuitive for positionals. If I have the following signature
sub foo(Str @bar, Str @xyz) { ; }
Then @bar
is a positional whose elements must be Str
, as is @xyz
. But if I use a type capture, things go weird:
sub assert-same(::T @a, T @b) { ; }
my Str @x = <i j>;
my Str @y = <x y>;
assert-same @x, @y;
# Type check failed in binding to parameter '@b';
# expected Positional[Array[Str]] but got Array[Str] (Array[Str].new("x", "y"))
It seems that the first type capture is capturing via .WHAT
(which makes sense for scalars) rather than .of
which to me is the intuitive sense for positionals, given that the immediate reuse of the capture would only work if .of
had been originally used.
This smells of a bug, but if it's by design, is there a way to enforce via type capture that two typed positionals have elements that are of the same type? In the meantime, I can use
sub assert-same(::T @a, @b where .all ~~ @a.of ) { ; }
my Str @x = <a b c>;
my Str @y = <x y z>;
my Int @i = 1,2,3;
assert-same @x, @y; # silent
assert-same @x, @i; # type check
But that seems a bit silly.
I think there are many bugs lurking in this area. I posted these a couple weeks ago:
(::T $, T @)
yields "Internal error: inconsistent bind result"
sub foo (::T $, Array[T] $) { }; foo Int, Array[Int]
yields "expected Array[T] but got Array[Int]";
I searched RT and the GH rakudo issues queue before posting them. In the latter I mention "cf #2595 and other type capture bugs". Maybe it's already in there; if not, please add an issue. TIA.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With