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/5213563 to your computer and use it in GitHub Desktop.
Save masak/5213563 to your computer and use it in GitHub Desktop.
Perl 6 can do ADTs, using classes. Kind of.
# data Tree a = Branch (Tree a) (Tree a) | Leaf a
class Tree { ... }
class Tree::Branch {
has Tree $.left;
has Tree $.right;
}
class Tree::Leaf {
has $.cargo;
}
class Tree {
has Tree::Branch $.branch handles <left right>;
has Tree::Leaf $.leaf handles <cargo>;
method new { die "Cannot construct Tree this way" };
method new-branch(Tree :$left!, Tree :$right!) {
self.bless(*, :branch( Tree::Branch.new(:$left, :$right) ));
}
method new-leaf($cargo) {
self.bless(*, :leaf( Tree::Leaf.new(:$cargo) ));
}
}
# We can still define convenient subtypes Branch and Leaf which
# specialize Tree.
subset Branch of Tree where { defined .branch };
subset Leaf of Tree where { defined .leaf };
my $tree = Tree.new-branch(
left => Tree.new-leaf(1),
right => Tree.new-branch(
left => Tree.new-leaf(2),
right => Tree.new-leaf(3),
),
);
say $tree ~~ Tree; # True
# Now it's suddenly silly to talk about those other types
# not smartmatching. They're simply not instances of the
# Tree class. So let's skip that.
# '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