sub can_merge { my ($i1, $i2) = @_; return $i1->{'type'} ne $2->{'type'} } sub merge { my ($i1, $i2, $distance) = @_; my $newi = {}; if( $distance ... ){ return undef } # no merge happened because distance etc. if( ! can_merge($i1, $i2) ){ return undef } # no merge, types incompatible. $newi->{from} = List::Util::min($i1->{from}, $i2->{from}); $newi->{to} = List::Util::max($i1->{to}, $i2->{to}); ... return $newi # return the new interval representing the merge }