[mercury-users] Mercury syntax?
Fergus Henderson
fjh at cs.mu.oz.au
Fri Aug 22 00:32:54 AEST 1997
Marko Schuetz, you wrote:
> Why is it not possible to use a data constructor as a curried
> relation between its arguments and its result?
>
> I would like to write:
>
> list__map(intersection(A), List1, List2) where intersection is a
> binary constructor. This is not accepted (mercury-0.6). But I can
> write:
>
> list__map((pred(K1::in, K2::out) is det :- K2 = intersection(B, K1))
> , List1
> , List2
> )
>
> Is there a strong reason to favor the latter over the former?
Well, you've asked whether data constructors should be equivalent to
predicates. But data constructors are actually much more like functions
than like predicates. So let me decompose your question into two issues:
1. Should data constructors be equivalent to functions?
2. Should functions be equivalent to predicates?
1. Should data constructors be equivalent to functions?
That is, should you be able to "take the address" of a data constructor,
i.e. pass it as a parameter to a higher-order function directly,
rather than using a lambda expression?
The reason that these two aren't equivalent in Mercury is that data constructors
are polymorphically moded, whereas functions have only a finite number
of modes -- typically just one. In Mercury, you can only directly take
the address of something which has one mode; for anything that has
multiple modes, you have to use an explicit lambda expression to
specify which mode you want to take the address of. Since data constructors
are polymorphically moded, you can't directly take their address.
The reason for the restriction that you can't take the address of
something which has more than one mode is that allowing that would
significantly increase the complexity of mode and determinism
analysis. We might consider relaxing this restriction at some point,
but the work-around is pretty easy -- just write an explicit lambda
expression -- and extending mode/determinism analysis to handle it
seems to be tricky... it may be better to keep the existing
mode/determinism system, even if it makes some programs a bit more
verbose.
2. Should functions be equivalent to predicates?
Note that the Mercury standard library predicate list__map/3 takes a predicate
as a argument, not a function. Even if you could directly "take the
address of" data constructors, they would be functions, not predicates,
you couldn't pass `intersection(A)' to `list__map'.
The short answer is that there is no simple isomorphism between
predicates and functions. You can either map predicates onto a subset
of functions (the functions that return a bool), or you can map
functions onto a subset of predicates (those that have at most one
solution for the last argument for each possible value of the first N-1
arguments). Since there is no compelling reason to prefer one of these
mappings above the other, Mercury does not make functions equivalent to
predicates.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the users
mailing list