+sub concat {
+ my ($left, $right, $rev) = @_;
+
+ $_body_tc->assert_valid($right);
+
+ $left = $left->flatten;
+
+ my (@left, @right);
+
+ if ($my_tc->check($right)) {
+ $right = $right->flatten;
+
+ my ($only_left, $common, $only_right) = $inter->(
+ $left->_mods_cache,
+ $right->_mods_cache,
+ );
+
+ if (@$common) {
+ my $x = $left->new
+ ->mod(@$only_left)
+ ->body($left->_body);
+ my $y = $left->new
+ ->mod(@$only_right)
+ ->body($right->_body);
+ ($x, $y) = ($y, $x) if $rev;
+ return $left->new
+ ->mod(@$common)
+ ->body($x . $y);
+ } else {
+ @right = $right->instantiate;
+ }
+ } else {
+ @right = @$right;
+ }
+
+ @left = $left->instantiate;
+
+ $left->new
+ ->body($rev ? [ @right, @left ] : [ @left, @right ]);
+}