foldl_index & map_index

This commit is contained in:
rhiannon morris 2022-12-16 16:29:37 +01:00
parent 1b57b12794
commit 2af4043f6a

View file

@ -15,8 +15,7 @@
:- pred output(answer::in, io::di, io::uo) is det. :- pred output(answer::in, io::di, io::uo) is det.
:- func ite((pred), T, T) = T. :- func ite((pred)::((pred) is semidet), T::in, T::in) = (T::out) is det.
:- mode ite((pred) is semidet, in, in) = out is det.
:- import_module list. :- import_module list.
@ -46,8 +45,27 @@
:- func replicate(int, T) = list(T). :- func replicate(int, T) = list(T).
:- func rev_sort(list(T)) = list(T). :- func rev_sort(list(T)) = list(T).
:- func map_index(func(int, T) = U, list(T)) = list(U). :- func map_index(func(int, T) = U, list(T)) = list(U).
:- pred map_index(pred(int, T, U), list(T), list(U)).
:- mode map_index(pred(in, in, out) is det, in, out) is det.
:- mode map_index(pred(in, di, uo) is det, di, uo) is det.
:- mode map_index(pred(in, in, out) is semidet, in, out) is semidet.
:- mode map_index(pred(in, in, out) is multi, in, out) is multi.
:- mode map_index(pred(in, in, out) is cc_multi, in, out) is cc_multi.
:- func foldl_index(func(int, T, U) = U, list(T), U) = U.
:- pred foldl_index(pred(int, T, U, U), list(T), U, U).
:- mode foldl_index(pred(in, in, in, out) is det, in, in, out) is det.
:- mode foldl_index(pred(in, in, di, uo) is det, in, di, uo) is det.
:- mode foldl_index(pred(in, di, di, uo) is det, di, di, uo) is det.
:- mode foldl_index(pred(in, in, in, out) is semidet, in, in, out) is semidet.
:- mode foldl_index(pred(in, in, in, out) is multi, in, in, out) is multi.
:- mode foldl_index(pred(in, in, in, out) is cc_multi, in, in, out) is cc_multi.
:- import_module maybe. :- import_module maybe.
@ -59,8 +77,7 @@
part("1", one). part("1", one).
part("2", two). part("2", two).
part(one, X, _) = X. part(P, X, Y) = ite(unify(P, one), X, Y).
part(two, _, Y) = Y.
output(int(I), !IO) :- write_int(I, !IO), nl(!IO). output(int(I), !IO) :- write_int(I, !IO), nl(!IO).
@ -82,10 +99,9 @@ die(Fmt, Args) :- die(format(Fmt, Args)).
wrap_main(Main, !IO) :- wrap_main(Main, !IO) :-
try [io(!IO)] Main(!IO) try [io(!IO)] Main(!IO)
then true then true
catch death(Err) -> ( catch death(Err) ->
format("%s\n", [s(Err)], !IO), format("%s\n", [s(Err)], !IO),
set_exit_status(1, !IO) set_exit_status(1, !IO).
).
need(ok(X), X). need(ok(X), X).
need(error(E), _) :- die(error_message(E)). need(error(E), _) :- die(error_message(E)).
@ -107,12 +123,38 @@ replicate(N, X) = Out :-
rev_sort(Xs) = sort(converse(ordering), Xs). rev_sort(Xs) = sort(converse(ordering), Xs).
:- func map_index(int, func(int, T) = U, list(T)) = list(U).
map_index(_, _, []) = [].
map_index(I, F, [X | Xs]) = [F(I, X) | map_index(I+1, F, Xs)].
map_index(F, Xs) = map_index(0, F, Xs). :- pred map_index(int, pred(int, T, U), list(T), list(U)).
:- mode map_index(in, pred(in, in, out) is det, in, out) is det.
:- mode map_index(in, pred(in, di, uo) is det, di, uo) is det.
:- mode map_index(in, pred(in, in, out) is semidet, in, out) is semidet.
:- mode map_index(in, pred(in, in, out) is cc_multi, in, out) is cc_multi.
:- mode map_index(in, pred(in, in, out) is multi, in, out) is multi.
map_index(_, _, [], []).
map_index(I, P, [X | Xs], [Y | Ys]) :- P(I, X, Y), map_index(I, P, Xs, Ys).
map_index(P, Xs, Ys) :- map_index(0, P, Xs, Ys).
map_index(F, Xs) = Ys :-
P = (pred(I::in, X::in, Y::out) is det :- Y = F(I, X)),
map_index(P, Xs, Ys).
:- pred foldl_index(int, pred(int, T, U, U), list(T), U, U).
:- mode foldl_index(in, pred(in, in, in, out) is det, in, in, out) is det.
:- mode foldl_index(in, pred(in, in, di, uo) is det, in, di, uo) is det.
:- mode foldl_index(in, pred(in, di, di, uo) is det, di, di, uo) is det.
:- mode foldl_index(in, pred(in, in, in, out) is semidet, in, in, out) is semidet.
:- mode foldl_index(in, pred(in, in, in, out) is multi, in, in, out) is multi.
:- mode foldl_index(in, pred(in, in, in, out) is cc_multi, in, in, out) is cc_multi.
foldl_index(_, _, [], !Acc).
foldl_index(I, P, [X | Xs], !Acc) :-
P(I, X, !Acc),
foldl_index(I + 1, P, Xs, !Acc).
foldl_index(P, Xs, !Acc) :- foldl_index(0, P, Xs, !Acc).
foldl_index(F, Xs, Start) = End :-
P = (pred(I::in, X::in, A::in, B::out) is det :- B = F(I, X, A)),
foldl_index(P, Xs, Start, End).
to_int_may(Str) = Out :- to_int_may(Str) = Out :-
if to_int(Str, N) then Out = yes(N) else Out = no. if to_int(Str, N) then Out = yes(N) else Out = no.