6

This question was originally posted by lookatme in the Perl6 IRC channel. The original intention is to constrain a Callable by using subsets or any other possible way. It works in signatures, however this:

subset WalkCb of Callable where *.signature ~~ :(Int $a); 
my WalkCb $x = sub (Int $a) { return $a; };

returns

«Type check failed in assignment to $x; expected WalkCb but got Sub (sub (Int $a) { #`(Sub...)␤  in block <unit> at <tmp> line 1␤␤»

Other variants of the declaration return similar messages. What would be the correct syntax?

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
jjmerelo
  • 22,578
  • 8
  • 40
  • 86

2 Answers2

7

A where constraint can take a block (lambda) or a statement.

… where { $_ == 42 }; # block
… where    * == 42;   # lambda
… where   $_ == 42;   # statement

The thing is that ~~ doesn't participate in the creation of WhateverCode lambdas (*)
So what you are really doing is creating a lambda of *.signature inside of a larger where statement (not lambda).

constant $lambda = *.signature;
subset WalkCb of Callable where $lambda ~~ :(Int $);

Which will of course never return True as the lambda has a signature of :(;; $ is raw)


So instead just write the statement form. (using implicit $_)

subset WalkCb of Callable where .signature ~~ :(Int $);
my WalkCb $x = sub (Int $a) { return $a }
say $x(42); # 42␤
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
6

It appears the WhateverCode parsing messes up in this case. So if you specify a block in the where:

subset WalkCb of Callable where { .signature ~~ :(Int $) }
my WalkCb $x = sub (Int $a) { return $a; }

it appears to work as expected. Also note that I removed the ; at the end of the lines, as a } at the end of a line is also the end of a statement. And that I removed the "a" from the signature: the name of of positional parameters in signature smartmatching is ignored.

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105