ychr-0.1.0.0: libraries/lists.chr
:- module(lists, [
fun cons/2,
fun head/1,
fun tail/1,
fun length/1,
fun member/2,
fun append/2,
fun maplist/2,
fun foldl/3,
fun sum_list/1,
fun product_list/1,
fun nth/2
]).
:- function
(cons(T, list(T)) -> list(T)),
(length(list(T)) -> int),
(member(T, list(T)) -> bool),
(append(list(T), list(T)) -> list(T)),
(maplist(fun(A) -> B end, list(A)) -> list(B)),
(foldl(fun(B, A) -> B end, B, list(A)) -> B),
(foldl_(fun(B, A) -> B end, list(A), B) -> B),
(sum_list(list(int)) -> int),
(product_list(list(int)) -> int).
% head/1, tail/1 and nth/2 are deliberately left untyped.
%
% They are partial -- there is no sensible `head([])` -- and the
% language currently offers no way to write the failing equation, since
% raising a runtime error from source is not expressible. A `list(T)`
% signature is what enables the exhaustiveness checker, so typing them
% would make every module that merely imports this library emit
% YCHR-20103, which is fatal under `--Werror`.
%
% Calling any of them on an empty list is a runtime error ("no matching
% equation") either way; only the static check differs.
:- function
head/1,
tail/1,
nth/2.
cons(X, Xs) -> [X|Xs].
head([X|_]) -> X.
tail([_|Xs]) -> Xs.
length([]) -> 0.
length([_|Xs]) -> length(Xs) + 1.
member(_, []) -> false.
member(X, [X|_]) -> true.
member(X, [_|Xs]) -> member(X, Xs).
append([], Ys) -> Ys.
append([X|Xs], Ys) -> cons(X, append(Xs, Ys)).
maplist(_, []) -> [].
maplist(F, [X|Xs]) -> cons('$call'(F, X), maplist(F, Xs)).
foldl(F, Init, Xs) -> foldl_(F, Xs, Init).
foldl_(F, [], Acc) -> Acc.
foldl_(F, [X|Xs], Acc) -> foldl_(F, Xs, '$call'(F, Acc, X)).
sum_list(Xs) -> foldl(fun '+'/2, 0, Xs).
product_list(Xs) -> foldl(fun '*'/2, 1, Xs).
nth(0, [X|_]) -> X.
nth(N, [_|Xs]) | N > 0 -> nth(N - 1, Xs).