[m-users.] Pattern matching in Mercury

Mark Brown mark at mercurylang.org
Sun Oct 26 20:02:28 AEDT 2014


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.



More information about the users mailing list