[m-users.] Pattern matching in Mercury

Roger Qiu roger.qiu at polycademy.com
Sun Oct 26 18:14:18 AEDT 2014


Ok so deterministic and semi-det functions and predicates requires that 
there can only be 1 valid clause (mutually exclusive clauses). The thing 
I’m confused about is how to reconcile this requirement with this simple 
example:

|:- func convert(int) = string.
convert(1) = "good".
convert(_) = "bad".
|

The above kind of setup would work in Erlang, in the sense I can pass 1, 
and then get “good” and if I pass anything else I would get “bad”. 
However such a thing is not possible in Mercury as if I pass 1, both 
clauses execute which of course results in an error.

I was suggesting that perhaps a guard clause would help here, so that I 
can still do pattern matching and ensure that there was only 1 valid 
clause by guarding /against/ 1 on the second convert clause.

    This leads to programs that tend to use structual induction-like
    predicate definitions.

Can you give me some examples as to what you’re referring to?

Thanks,
Roger

On 26/10/2014 5:55 PM, Paul Bone wrote:

> 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.
>
>
​

-- 
Founder of Matrix AI
http://matrix.ai/
+61420925975

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20141026/239a1087/attachment.html>


More information about the users mailing list