From 2af4043f6a09ec65d09a171acbd52b302db78c14 Mon Sep 17 00:00:00 2001 From: rhiannon morris Date: Fri, 16 Dec 2022 16:29:37 +0100 Subject: [PATCH] foldl_index & map_index --- basics.m | 64 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/basics.m b/basics.m index bf2444a..452571e 100644 --- a/basics.m +++ b/basics.m @@ -15,8 +15,7 @@ :- pred output(answer::in, io::di, io::uo) is det. -:- func ite((pred), T, T) = T. -:- mode ite((pred) is semidet, in, in) = out is det. +:- func ite((pred)::((pred) is semidet), T::in, T::in) = (T::out) is det. :- import_module list. @@ -46,8 +45,27 @@ :- func replicate(int, T) = list(T). :- func rev_sort(list(T)) = list(T). + :- 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. @@ -59,8 +77,7 @@ part("1", one). part("2", two). -part(one, X, _) = X. -part(two, _, Y) = Y. +part(P, X, Y) = ite(unify(P, one), X, Y). 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) :- try [io(!IO)] Main(!IO) then true - catch death(Err) -> ( + catch death(Err) -> format("%s\n", [s(Err)], !IO), - set_exit_status(1, !IO) - ). + set_exit_status(1, !IO). need(ok(X), X). need(error(E), _) :- die(error_message(E)). @@ -107,12 +123,38 @@ replicate(N, X) = Out :- 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 :- if to_int(Str, N) then Out = yes(N) else Out = no.