What type are Lists of any type in Perl 6?

人走茶凉 提交于 2020-01-14 13:00:07

问题


Consider the following Python code (as an example):

a = 5 
b = "a"
l = [a, b] # -> typing.List[typing.Any]
print(l)   
# [5, "a"]

The type of list l is list; it is not constrained by the types it holds because Python is quite dynamically typed.

Contrast this with, say, Go, which is strongly structurally typed:

var list []uint8{1, 2, 3, 4, 5, 6}

That list can only hold unsigned integers up to 255. It cannot hold any other type.

Also Go:

var multi interface{"string", []int{9, 5}, rune('5'), []interface{}}

Interfaces allow for containers of variant types.


Consider Perl 6, which is even more dynamically typed than Python in that say 6 + "1"; will give 7, the integer. (Who thought this was a good idea I don't know.)

I like gradual typing in my programs as (especially for Perl 6, which I'm learning) it improves readability and maintanability.

Neither of the following work:

use strict;
my Int $n = 6;
my Str $x = "a";
my Int @l = $n, $x;

nor

use strict;    
my Int $n = 6;
my Str $x = "a";
my List @l = $n, $x;

You get Type check failed in assignment to @l; expected List but got Int. (Other list construction syntaxes ([vals], <vals>) give the same error).

What does work is saying the type is Any (or Mu) which makes sense. (Well, it makes sense to me because Any's the same keyword Python 3.5 uses.)

use strict;    
my Int $n = 6;
my Str $x = "a";
my Any @l = $n, $x;

But using Any or Mu kinda defeats the purpose of type checking in the first place.

What's the type of a list, if it's not List? Moreover, why is my List $blah; valid syntax if the type check will never pass for any value or List thereof?


回答1:


You interpreted it wrong, at least list in Python is different from list in Perl6, it's actually like array in Perl6 (and Perl6 list is like Python tuple).

When you do:

my List @l = $n, $n;

you create an array @l and enforce all its elements must be type List.

So your second example:

use strict;
my Int $n = 6;
my Int @l = $n, $n;

must work.

The code:

my Any @l = $n, $x;

is the same as:

my @l = $n, $x;

You have allowed the elements of array @l to be any type.




回答2:


If you want elements of a list to be type-checked, then you can use binding := instead of assignment =:

my Int $n =   6;
my Str $x = "a";

# Bind $n and $x to elements of @bound
my @bound := $n, $x;

@bound[1].say;       # Prints "a"
@bound[1] = "Hello"; # Changing the second element changes $x
$x.say;              # Prints "Hello"

@bound[1] = 6; # Dies with error "Type check failed in assignment to $x; expected Str but got Int"

Notice that the error created by that last line refers to $x, not @bound[1].



来源:https://stackoverflow.com/questions/34997353/what-type-are-lists-of-any-type-in-perl-6

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!