I think the closest things we've got to pattern matching come from a
combination of multiple dispatch, where clauses and signature
unpacking. I don't know much about the latter, but a where clause can
discriminate multiple dispatch variants based on parameter values
rather than just the type, so you can say:

multi doSomething(@a where { .elems == 0 }) {
  # empty arrays only
}

multi doSomething(@a where { .elems >= 3 && .[2] == 4 }) {
  # arrays with a third element numerically equal to 4
}

multi doSomething(@a) {
  # anything else
}

Which is pretty powerful, really.

> This is a contrived example of what I'm referring to:
>
> sub traverse([Leaf $a]) {
>  # do something
> }
>
> sub traverse([Tree $left, Tree $right]) {
>  traverse($left);
>  traverse($right);
> }
>
> my $t = Tree(...);
> traverse($t);

You could do most of this with multidispatch and where clauses. It
doesn't quite work because of the unpacking which pattern matching
does, and also because Perl 6 data structures don't get built in the
same way that Haskell ones do, and you've used a Haskell-like syntax
for Leaf and Tree and so forth.

Now, while it might be nice to say let me write a signature which
accepts a Tree object which has a left and right subtree, and binds
them to $left and $right respectively, arguably a where clause can
check that the subtrees exist, and your tree class should have good
accessors for the subtrees which make unpacking them a little
pointless. This is where Perl 6 is not the same as functional
languages, since it's got an imperative OO element as well.

multi traverse(Tree $t where { all(.left, .right).defined }) { ... }

Perhaps.

Reply via email to