[m-users.] Pattern matching in Mercury
Paul Bone
paul at bone.id.au
Sun Oct 26 17:55:17 AEDT 2014
On Sun, Oct 26, 2014 at 05:19:56PM +1100, Roger Qiu wrote:
> Hello everybody,
>
> According to this:
> http://stackoverflow.com/questions/7466833/mercury-determinism-and-pattern-matching
>
> Mercury does not pattern match in a linear order. I'm used to the
> pattern matching in Erlang, and it works by going by the first one that
> matches. However this does not work in Mercury, all the clauses need to
> be fully mutually exclusive.
That's not true, at least not that way you've stated it.
_Determinstic_ code requires all clauses to be mutually exclusive. But this
is not true of code that can succeed more than once (multi or nondet code).
It might be best to think of it more like this:
foo([], ...).
foo([X | Xs], ...) :-
something.
foo([X | Xs], ...) :-
something else.
If foo is passed a non empty list _both_ the second and third clauses are
executed. If both of them return results then all of those results may be
returned and foo is nondet or multi. If foo were declared as det then the
compiler would give you an error because a det predicate can't have more
than one answer and therefore it cannot have more than one clause that is
executed (and produce a solution).
So pattern matching is indeed different. The first clause to match _is_
executed, but so is every other matching clause. If there are multiple
clauses (or disjuncts) that could be executed then the procedure must be
multi or nondet. It could be semidet but only if it produces no variable
bindings - however that's another topic.
If you're only writing det code then only one valid clause may exist. In
our experience this is a good habbit/discipline for programmers and makes
program's meanings clearer. This leads to programs that tend to use
structual induction-like predicate definitions.
> The pattern matching on the arguments are not sufficient enough to setup
> mutually exclusive clauses. I have an idea that perhaps guard statements
> on the clauses might help these situations, and allow one to retain
> "clause-like" switches instead of defaulting on the if-then-else
> pattern. What do you think?
I can see how guards could be used in Mercury but I've never felt that the
need for guards is particulary strong in either Mercury or Haskell.
Some prolog-like languages used guards, like Guarded Horne Clauses (yes
that's the language's name). In this case is was to address the
program's evaluation order making it safe for parallel programming. It
wasn't added to the language to help the programmer, but to help the
runtime.
--
Paul Bone
More information about the users
mailing list