Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subsetting Blocks (or Callables in general)

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?

like image 213
jjmerelo Avatar asked May 17 '18 06:05

jjmerelo


2 Answers

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␤
like image 141
Brad Gilbert Avatar answered Oct 17 '22 03:10

Brad Gilbert


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.

like image 21
Elizabeth Mattijsen Avatar answered Oct 17 '22 02:10

Elizabeth Mattijsen