-module(ask@eq). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([trivial/0, default/0, 'and'/2, 'or'/2, negate/1, list/1, pair/2, map_input/2, contains/1, unique/1]). -spec trivial() -> fun((FLQ, FLQ) -> boolean()). trivial() -> fun(_, _) -> true end. -spec default() -> fun((FLS, FLS) -> boolean()). default() -> fun(Value, Other) -> Value =:= Other end. -spec 'and'(fun((FLU, FLU) -> boolean()), fun((FLU, FLU) -> boolean())) -> fun((FLU, FLU) -> boolean()). 'and'(First, Second) -> fun(Value, Other) -> First(Value, Other) andalso Second(Value, Other) end. -spec 'or'(fun((FLY, FLY) -> boolean()), fun((FLY, FLY) -> boolean())) -> fun((FLY, FLY) -> boolean()). 'or'(First, Second) -> fun(Value, Other) -> First(Value, Other) orelse Second(Value, Other) end. -spec negate(fun((FMC, FMC) -> boolean())) -> fun((FMC, FMC) -> boolean()). negate(Eq) -> fun(Value, Other) -> not Eq(Value, Other) end. -spec do_list(fun((FMF, FMF) -> boolean()), list(FMF), list(FMF), boolean()) -> boolean(). do_list(Eq, Values, Others, Acc) -> case {Values, Others} of {[], []} -> Acc; {[Value | Values@1], [Other | Others@1]} -> do_list(Eq, Values@1, Others@1, Acc andalso Eq(Value, Other)); {_, _} -> false end. -spec list(fun((FMJ, FMJ) -> boolean())) -> fun((list(FMJ), list(FMJ)) -> boolean()). list(Eq) -> fun(Values, Others) -> gleam@bool:guard( erlang:length(Values) /= erlang:length(Others), false, fun() -> do_list(Eq, Values, Others, true) end ) end. -spec pair(fun((FMN, FMN) -> boolean()), fun((FMP, FMP) -> boolean())) -> fun(({FMN, FMP}, {FMN, FMP}) -> boolean()). pair(First, Second) -> fun(Value, Other) -> case {Value, Other} of {{Value1, Value2}, {Other1, Other2}} -> First(Value1, Other1) andalso Second(Value2, Other2) end end. -spec map_input(fun((FMS, FMS) -> boolean()), fun((FMU) -> FMS)) -> fun((FMU, FMU) -> boolean()). map_input(Eq, Fun) -> fun(Value, Other) -> Eq(Fun(Value), Fun(Other)) end. -spec do_contains(fun((FMW, FMW) -> boolean()), list(FMW), FMW, boolean()) -> boolean(). do_contains(Eq, List, Elem, Acc) -> case List of [] -> Acc; [X | Xs] -> do_contains(Eq, Xs, Elem, Acc orelse Eq(X, Elem)) end. -spec contains(fun((FNA, FNA) -> boolean())) -> fun((list(FNA), FNA) -> boolean()). contains(Eq) -> fun(List, Elem) -> do_contains(Eq, List, Elem, false) end. -spec do_unique(fun((FND, FND) -> boolean()), list(FND), list(FND)) -> list(FND). do_unique(Eq, List, Acc) -> case List of [] -> lists:reverse(Acc); [X | Xs] -> do_unique( Eq, Xs, gleam@bool:guard( (contains(Eq))(Acc, X), Acc, fun() -> [X | Acc] end ) ) end. -spec unique(fun((FNI, FNI) -> boolean())) -> fun((list(FNI)) -> list(FNI)). unique(Eq) -> fun(List) -> do_unique(Eq, List, []) end.