[m-users.] Pattern matching in Mercury

Left Right olegsivokon at gmail.com
Sun Oct 26 21:44:27 AEDT 2014


If I may add my 2 cents... I started looking into Mercury about half a
year ago, then I realized that there are things I don't quite
understand about the language. I think that I found a good book, even
though it's about Prolog, it explained the formalisms used to build
the language and the consequences of using these formalisms. I'm
talking about The Art of Prolog by Sterling and Shapiro. I can't point
you to the exact chapter in the book, where it talks about unifying
(something that you call pattern matching). But, to put it simply:
pattern matching and unifying aren't the same thing. They also
describe different things (so they aren't two different tools to do
the same task, they also accomplish different tasks).

The specific problem you are facing is because of the optimization.
The book (typically of all books on programming languages) shows how
to produce natural numbers via:

s(0).
s(s(N)).

If natural numbers were defined this way, you wouldn't have the
problem with nth/3 predicate. But this would be very inefficient... so
you'd have to accept a less general way of dealing with numbers, which
has an unfortunate consequence of having to write predicates, where
you may not infer whether same number can or cannot satisfy both
descriptions.

Best,

Oleg

On Sun, Oct 26, 2014 at 11:02 AM, Mark Brown <mark at mercurylang.org> wrote:
> On Sun, Oct 26, 2014 at 6:14 PM, Roger Qiu <roger.qiu at polycademy.com> wrote:
>> 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.
>
> A relevant part of the language spec is switch detection, in section
> 6.2. Switch detection only considers unifications near the start of
> each disjunct; in particular it doesn't consider inequalities or
> disequalities.
>
> For your example, you may want to write
>
>     convert(1) = "good".
>     convert(X) = "bad" :- X \= 1.
>
> but this is not detected as a switch. Or maybe you would like
>
>     convert(X) = "good" :- X > 1.
>     convert(X) = "bad" :- X =< 1.
>
> but this is not a switch either. Note that we still are defining
> exactly one result for each input, as the determinism says.
>
> Rules could be added to switch detection to cover these cases, and
> that could be done without any special syntax for guards. That would
> benefit programmers, and I think would provide what you are asking
> for. But, like Paul, I'm not yet convinced that the implementation and
> maintenance costs would be justified.
>
> Cheers,
> Mark.
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://www.mercurylang.org/lists/listinfo/users



More information about the users mailing list