:- module basics. :- interface. :- import_module io. :- type part ---> one; two. :- pred part(string, part). :- mode part(in, out) is semidet. :- mode part(out, in) is det. :- func part(part, T, T) = T. :- type answer ---> int(int); string(string); lines(list(string)). :- 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. :- import_module list. :- import_module string. :- type lines == list(string). :- pred die(string::in) is erroneous. :- pred die(string::in, list(poly_type)::in) is erroneous. :- pred need(io.res(T)::in, T::out) is det. :- pred read_lines_need(string::in, lines::out, io::di, io::uo) is det. :- pred wrap_main(pred(io, io), io, io). :- mode wrap_main(pred(di, uo) is cc_multi, di, uo) is cc_multi. :- mode wrap_main(pred(di, uo) is det, di, uo) is cc_multi. :- import_module char. :- type chars == list(char). :- import_module int. :- func sum(list(int)) = int. :- func replicate(int, T) = list(T). :- func map_index(func(int, T) = U, list(T)) = list(U). :- import_module maybe. :- func to_int_may(string) = maybe(int). :- implementation. part("1", one). part("2", two). part(one, X, _) = X. part(two, _, Y) = Y. output(int(I), !IO) :- write_int(I, !IO), nl(!IO). output(string(S), !IO) :- write_string(S, !IO), nl(!IO). output(lines(Ss), !IO) :- write_list(Ss, "\n", write_string, !IO), nl(!IO). ite(P, T, E) = X :- if P then X = T else X = E. :- import_module exception. :- type die ---> death(string). die(Str) :- throw(death(Str)). die(Fmt, Args) :- die(format(Fmt, Args)). wrap_main(Main, !IO) :- try [io(!IO)] Main(!IO) then true catch death(Err) -> ( format("%s\n", [s(Err)], !IO), set_exit_status(1, !IO) ). need(ok(X), X). need(error(E), _) :- die(error_message(E)). read_lines_need(File, Lines, !IO) :- read_named_file_as_lines(File, Res, !IO), need(Res, Lines). sum(Xs) = foldl(plus, Xs, 0). replicate(N, X) = Out :- if N = 0 then Out = [] else Out = [X | replicate(N - 1, X)]. :- 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). to_int_may(Str) = Out :- if to_int(Str, N) then Out = yes(N) else Out = no.