Skip to content

Instantly share code, notes, and snippets.

@masak
Last active December 15, 2015 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masak/5213423 to your computer and use it in GitHub Desktop.
Save masak/5213423 to your computer and use it in GitHub Desktop.
Yes, Perl 6 can do ADTs. Sort of.
# data Tree a = Branch (Tree a) (Tree a) | Leaf a
subset Tree of Hash where &is_branch | &is_leaf;
sub is_branch($_) {
.keys == 2
&& .exists('left')
&& .<left> ~~ Tree
&& .exists('right')
&& .<right> ~~ Tree
}
sub is_leaf($_) {
.keys == 1
&& .exists('cargo')
}
# We can construct nice subtypes from the subroutines,
# too.
subset Branch of Tree where &is_branch;
subset Leaf of Tree where &is_leaf;
# Just by using subtypes, we have basically co-opted
# smartmatching, which is a big part of the battle won.
my $tree = {
left => { cargo => 1 },
right => {
left => { cargo => 2 },
right => { cargo => 3 },
},
};
say $tree ~~ Tree; # True
say {
left => "lol, not a Tree"
} ~~ Tree; # False
say "also not a Tree" ~~ Tree; # False
# 'when' statements are basically sugar for smartmatching,
# and so they work, too. This allows us to
sub sum_leaves(Tree $_) {
when Branch { sum_leaves(.<left>) + sum_leaves(.<right>) }
when Leaf { .<cargo> }
}
say sum_leaves($tree); # 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment