packages feed

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).