Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where can I learn about perl6 Type variables (::T)

Tags:

raku

I need to use perl6 type variables. It seems that the definitive manual is here http://www.jnthn.net/papers/2008-yapc-eu-perl6types.pdf, which is concise and v. useful in so far as it goes.

Is there anything more comprehensive or authoritative that I can be pointed to?

like image 347
p6steve Avatar asked Jun 08 '18 21:06

p6steve


Video Answer


2 Answers

What you're referring to is called "type capture" in perl6, here's two pages about them:

  • Type Captures in function/method signatures: https://docs.perl6.org/type/Signature#index-entry-Type_Capture_%28signature%29
  • Type Captures in Roles: https://docs.perl6.org/language/typesystem#index-entry-Type_Capture_%28role%29

Hope that helps!

like image 123
timotimo Avatar answered Sep 20 '22 23:09

timotimo


The way I like to think of it is that Int is really short for ::Int.

So most of the time that you are talking about a type, you can add the :: to the front of it.

Indeed if you have a string and you want to use it to get the type with the same short name you use ::(…)

my $type-name = 'Int';
say 42 ~~ ::($type-name); # True

The thing is that using a type in a signature is already used to indicate that the parameter is of that type.

->   Int $_   {…}

Any unsigiled identifier in a signature is seen as the above, so the following throws an error if there isn't a foo type.

->   foo   {…}

What you probably want in the situation above is for foo to be a sigiless variable. So you have to add a \ to the front. (Inside of the block you just use foo.)

->   \foo   {…}

So if you wanted to add a feature where you capture the type, you have to do something different than just use an identifier. So obviously adding :: to the front was chosen.

->   ::foo   { say foo }

If you call it with the number 42, it will print (Int).


You can combine these

-> Real ::Type \Value {…}

The above only accepts a real number (all numerics except Complex), aliases the type to Type, and aliases the number to Value

sub example ( Real ::Type \Value ) {
  my Type $var = Value;

  say Type;
  say Value;
}
> example 42;
(Int)
42

> example ''
Type check failed in binding to parameter 'Value'; expected Real but got Str ("")
  in block <unit> at <unknown file> line 1

> example 42e0
(Num)
42

This is also used in roles.

role Foo[ Real ::Type \Value ] {
  has Type $.foo = Value; # constrained to the same type as Value
}
class Example does Foo[42] {}

say Example.new( :foo(128) ).foo; # 128
say Example.new().foo;            # 42

say Example.new( :foo(1e0) );     # Type check error

You can of course leave off any part that you don't need.

role Foo[::Type] {…}
like image 20
Brad Gilbert Avatar answered Sep 20 '22 23:09

Brad Gilbert