[m-dev.] Suggested interface for sequence types in lib-v2
Fergus Henderson
fjh at cs.mu.OZ.AU
Sat Oct 21 00:49:34 AEDT 2000
On 20-Oct-2000, Ralph Becket <rbeck at microsoft.com> wrote:
> This is a very rough first cut spec. for the interface to sequence
> types for v2 of the std library. For now, conforming to the
> interface will have to be by convention since the typeclass system
> isn't up to the job (we need functional dependencies).
Great stuff, Ralph -- this looks good.
> % SEQUENCES
>
> :- type seq(T). % A sequence of T objects.
> :- func head(seq(T)) = T.
> :- func semidet_head(seq(T)) = T.
You want
:- func semidet_head(seq(T)) = T is semidet.
^^^^^^^^^^^
But see below about naming conventions.
> :- func but_last(seq(T)) = seq(T).
> :- func semidet_but_last(seq(T)) = seq(T) is semidet.
What is that supposed to do?
Is it supposed to return the second-last element in the sequence (if any)?
If so, I think it would be better to name it `second_last'.
But I don't think that it is useful enough to justify inclusion
in the standard library.
> :- pred project_member(seq(T)::in, T::out) is nondet.
What is that supposed to do?
How does it differ from `member'?
> :- func rev_append(seq(T), seq(T)) = seq(T).
What is that supposed to do?
> % XXX Is this really useful?
> :- func condense_map(func(T1) = seq(T2), seq(T1)) = seq(T2).
Is this just
condense_map(F, S) = condense(map(F, S)).
?
If so, I don't think it is worth including, unless there
are some sequences for which condense_map(F, S) can be implemented
more efficiently than condense(map(F, S)). Off-hand I don't know
of any such sequences.
> % REMOVING MEMBERS
>
> % Error unless S `contains` X.
> :- func delete_first(T, seq(T)) = seq(T).
I think that should be semidet.
A det `delete_first_det' might be useful, but
I think the semidet one is probably more useful.
> % INDEX BASED OPERATIONS
> % index_in(S, head(S)) = 0.
> :- func index_in(seq(T), T) = int. % Error unless S `contains` X.
> :- func semidet_index_in(seq(T), T) = int is semidet.
Our traditional naming scheme for these kind of things has been
for the semidet one to have the unadorned name, and for the
det one to get a `_det' suffix. I think this is a better idea,
since the explicit `_det' suffix serves as a hint that the procedure
might call error/1 in some circumstances, and so the programmer
had better be careful to ensure that the parameters at each call
meet the preconditions.
> :- func lookup(seq(T), int) = T. % Error unless 0 =< I < length(S).
> :- func seq(T) @ int = T. % Synonym for lookup/2.
> :- func semidet_lookup(seq(T), int) = T.
I'd rather semidet_lookup be named `search'.
This is used very frequently.
> % replace(S, I, X) = take_n(I - 1, S) ++ cons(X, drop_up_to_n(I, S))
> % Error unless 0 =< I < length(S).
> %
> :- func replace(seq(T), int, T) = seq(T).
>
> % change(S, I, F) = take_n(I - 1, S) ++ cons(F(lookup(S, I)), drop_n(I,
> S))
> % Error unless 0 =< I < length(S).
> %
> :- func change(seq(T), int, func(T) = T) = seq(T).
So is change(S, I, F) = replace(S, I, F(S `lookup` I))?
If so, then (a) that would be a simpler way of documenting it
and (b) is it really worth including in the standard library?
--
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list