finish adding type constraints
[scpubgit/DX.git] / lib / DX / ResolutionStrategy.pm
CommitLineData
7f385fb2 1package DX::ResolutionStrategy;
2
113f21b9 3use DX::Resolution;
22d29594 4use Types::Standard qw(CodeRef Tuple slurpy);
7f385fb2 5use DX::Class;
6
22d29594 7has action_prototypes => (
8 is => 'ro', required => 1,
9 isa => ArrayRef[Tuple[Value, Str, slurpy ArrayRef[Value]]]
10);
7f385fb2 11
22d29594 12has veracity_depends_on_builder => (
13 is => 'ro', required => 1, isa => CodeRef
14);
7f385fb2 15
22d29594 16has implementation_candidates => (
17 is => 'ro', required => 1, isa => ArrayRef[ArrayRef[ArrayRef[Value]]]
18);
7f385fb2 19
113f21b9 20sub next_resolution {
21 my ($self) = @_;
22 return undef unless my ($first) = @{$self->implementation_candidates};
23 my @ap = @{$self->action_prototypes};
24 my @cand = @$first;
25 return DX::Resolution->new(
26 actions => [
27 map {
28 my ($inv, $type, @args) = @{$ap[$_]};
29 $inv->${\"action_for_${type}"}(@args, @{$cand[$_]});
30 } 0..$#ap
31 ],
32 veracity_depends_on => $self->veracity_depends_on_builder->(@cand),
33 );
34}
35
36sub remainder {
37 my ($self) = @_;
38 my ($first, @rest) = @{$self->implementation_candidates};
39 return () unless @rest;
40 return $self->but(implementation_candidates => \@rest);
41}
42
c99dbb05 43sub for_deparse {
44 my ($self) = @_;
6162b001 45 [ word_and_body => [
46 'resolution_strategy',
c99dbb05 47 [ pairs => [
48 [ action_prototypes => [ block => [
49 map {
50 my ($inv, $type, @args) = @$_;
51 [ statement => [
52 [ symbol => $type ],
53 [ value_path => $inv->value_path ],
54 @args
55 ] ]
56 } @{$self->action_prototypes}
57 ] ] ],
6162b001 58 [ implementation_candidates => [ list => [
59 map [ list => [
60 map [ list => [
c99dbb05 61 map +($_->value_path ? [ value_path => $_->value_path ] : $_), @$_
62 ] ], @$_
63 ] ], @{$self->implementation_candidates}
64 ] ] ]
65 ] ],
66 ] ];
67}
68
7f385fb2 691;