[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