package TypedArray; use Moose; has type => ( is => 'ro', isa => 'Moose::Meta::TypeConstraint', required => 1 ); has elems => ( is => 'ro', isa => ArrayRef, default => sub { [] }, ); sub BUILD { my $self = shift; $self->type->assert_valid($_) for @{$self->elems}; } sub elems_push { my $self = shift; $self->type->assert_valid($_) for @_; push @{$self->elems}, @_; } ... more methods and operator overloads ... #### TypedArray->new(type => Int, elems => [4, 8, -7]) #### TypedArray->new(Int, 4, 8, -7) #### typedArray Int, 4, 8, -7 #### subtype TypedArrayOf as Parameterizable['TypedArray', 'Moose::Meta::TypeConstraint'], where { my ($typed_array, $type) = @_; $typed_array->type->is_a_type_of($type) }, message { my ($typed_array, $type) = @_; return "expected TypedArrayOf[$type], found TypedArrayOf[@{[$typed_array->type]}]" }; #### TypedArray[Int]