[m-users.] switch confusion with cc_multi
Julian Fondren
jfondren at minimaltype.com
Wed Aug 21 02:44:33 AEST 2019
On 2019-08-20 11:06, Mark Brown wrote:
> On Tue, Aug 20, 2019 at 3:20 AM Zoltan Somogyi
> <zoltan.somogyi at runbox.com> wrote:
>>
>> On Mon, 19 Aug 2019 14:17:31 +0100, emacstheviking <objitsu at gmail.com>
>> wrote:
>> > Every time I use multiple predicates with (_,..) as the event
>>
>> What does this mean? If you don't show us the actual code, we cannot
>> tell you
>> what is wrong with it. We can only guess, as the previous two replies
>> have done,
>> which may only confuse you further.
>
> Code was posted, and the relevant predicate was referred to by name.
> The code compiles fine with a reasonable type declaration so long as
> it doesn't have user defined equality or comparison, but if it does
> the compiler reports that a unification has multiple solutions. That
> is why I asked about that feature.
The code that was posted isn't the code that he had a problem with
though. "Every time I use multiple predicates with (_,..)" <- so when,
*instead* of the posted code, he tries writing multiple clauses where
one of the clauses uses a _ catch-all, he gets this problem: that the _
means the predicate isn't deterministic anymore, because every event he
wants to handle, he's also handling with the catch-all.
I think this is pretty clearly what the question is about, but without
code it's arguable that I'm guessing. And, I didn't understand your
reply at all, so clearly there are other potential interpretations of
the question :)
Mercury FAQ for people from FP langs with pattern-matching (SML, OCaml,
Erlang, Haskell, even Rust):
Q. Why isn't this deterministic?
:- func handle(bool) = string.
handle(yes) = "the bool was 'yes'".
handle(_) = "the bool was something else".
A. Unlike in FP langs with pattern-matching, these clauses aren't
ordered and the _ isn't a "catch-all" that in this code will only ever
match 'no' after the 'no' fails to match against the first clause. This
is a disjunction and only one clause must be true; because _ also
matches yes, both clauses define solutions for handle(yes), so this must
be (at least) a 'multi' rule.
As a rule, you can
1. exhaustively match all the cases to achieve a deterministic
disjunction.
handle(yes) = "...".
handle(no) = "...".
or
:- type other_thing ---> yes ; no ; maybe.
:- func handle(other_thing) = string.
handle(yes) = "the other thing was 'yes'".
handle(X) = _ :-
( X = no ; X = maybe ),
throw(not_implemented).
2. wrap an incomplete disjunction in a conditional, with the 'else' part
of the conditional as your catch-all.
handle(B) = R :-
( if X = yes, R0 = "ok" ; X = no, R0 = "denied" then
R = R0
else
throw(not_implemented)
).
3. drop down to semidet determinism, allowing for failure and no 'else'
case.
:- func handle(bool::in) = (string::out) is semidet.
handle(yes) = "the bool was 'yes'".
% nothing else.
As a rule, you SHOULD NOT EVER
1. replace 'det' with 'cc_multi'. It will only accidentally seem to do
what you want.
>> only det code may do I/O.
>
> cc_multi code may do I/O.
>
> Mark
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
More information about the users
mailing list