-module(ask@equivalence). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([trivial/0, 'and'/2, 'or'/2, 'not'/1, list/1, pair/2, map_input/2]). -spec trivial() -> fun((FLQ, FLQ) -> boolean()). trivial() -> fun(_, _) -> true end. -spec 'and'(fun((FLS, FLS) -> boolean()), fun((FLS, FLS) -> boolean())) -> fun((FLS, FLS) -> boolean()). 'and'(First, Second) -> fun(Value, Other) -> First(Value, Other) andalso Second(Value, Other) end. -spec 'or'(fun((FLW, FLW) -> boolean()), fun((FLW, FLW) -> boolean())) -> fun((FLW, FLW) -> boolean()). 'or'(First, Second) -> fun(Value, Other) -> First(Value, Other) orelse Second(Value, Other) end. -spec 'not'(fun((FMA, FMA) -> boolean())) -> fun((FMA, FMA) -> boolean()). 'not'(Eq) -> fun(Value, Other) -> not Eq(Value, Other) end. -spec do_list(fun((FMD, FMD) -> boolean()), list(FMD), list(FMD), 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((FMH, FMH) -> boolean())) -> fun((list(FMH), list(FMH)) -> 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((FML, FML) -> boolean()), fun((FMN, FMN) -> boolean())) -> fun(({FML, FMN}, {FML, FMN}) -> 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((FMQ, FMQ) -> boolean()), fun((FMS) -> FMQ)) -> fun((FMS, FMS) -> boolean()). map_input(Eq, Fun) -> fun(Value, Other) -> Eq(Fun(Value), Fun(Other)) end.