Current section
Files
Jump to
Current section
Files
src/fluoresce.erl
-module(fluoresce).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([compose/2, wrap/1, bind/2, join/1, co/2, callcc/1, apply/2, throw/2]).
-export_type([cont/2]).
-type cont(FQU, FQV) :: {cont, fun((fun((FQV) -> FQU)) -> FQU)}.
-spec compose(fun((FRD) -> FRE), fun((FRF) -> FRD)) -> fun((FRF) -> FRE).
compose(F, G) ->
fun(X) -> F(G(X)) end.
-spec wrap(FRG) -> cont(any(), FRG).
wrap(A) ->
{cont, fun(K) -> K(A) end}.
-spec bind(cont(FRK, FRL), fun((FRL) -> cont(FRK, FRO))) -> cont(FRK, FRO).
bind(C, F) ->
{cont,
fun(K) ->
(erlang:element(2, C))(fun(A) -> (erlang:element(2, F(A)))(K) end)
end}.
-spec join(cont(FRT, cont(FRT, FRU))) -> cont(FRT, FRU).
join(A) ->
{cont,
fun(K) ->
(erlang:element(2, A))(fun(B) -> (erlang:element(2, B))(K) end)
end}.
-spec co(
fun((fun((FSC) -> FSB)) -> cont(FSB, FSF)),
fun(({ok, FSF} | {error, FSC}) -> cont(FSB, FSK))
) -> cont(FSB, FSK).
co(F, Rest) ->
{cont,
fun(K) ->
K2 = fun(A) -> (erlang:element(2, Rest(A)))(K) end,
(erlang:element(
2,
F(compose(K2, fun(Field@0) -> {error, Field@0} end))
))(compose(K2, fun(Field@0) -> {ok, Field@0} end))
end}.
-spec callcc(fun((fun((FSQ) -> FSP)) -> FSQ)) -> cont(FSP, FSQ).
callcc(F) ->
co(fun(K) -> wrap(F(K)) end, fun(S) -> _pipe = case S of
{error, A} ->
A;
{ok, A@1} ->
A@1
end,
wrap(_pipe) end).
-spec apply(cont(FSV, {ok, FSW} | {error, FSX}), fun((FSX) -> FSV)) -> cont(FSV, FSW).
apply(E, Not_a) ->
{cont, fun(K) -> (erlang:element(2, E))(fun(Res) -> case Res of
{error, A} ->
Not_a(A);
{ok, E@1} ->
K(E@1)
end end) end}.
-spec throw(FTG, fun((FTG) -> FTH)) -> cont(FTH, any()).
throw(A, Not_a) ->
Instant_fail = wrap({error, A}),
apply(Instant_fail, Not_a).