Packages

The Phi Programming Language

Current section

Files

Jump to
phi priv Control Monad.erl
Raw

priv/Control/Monad.erl

%%---------------------------------------------------------------------------
%% |
%% Module : Monad
%% Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
%% License : BSD-style (see the LICENSE file)
%%
%% Maintainer : Feng Lee, feng@emqx.io
%% Yang M, yangm@emqx.io
%% Stability : experimental
%% Portability : portable
%%
%% The Monad FFI module.
%%
%%---------------------------------------------------------------------------
-module('Control.Monad.FFI').
-export([ applyListImpl/2
, listAppend/2
, bindImpl/2
, bindListImpl/2
, pureImpl/1
, seqio/1
, seqio_/1
, unsafePerformIO/1
, replApply/1
]).
-type mapFun() :: fun((A :: any()) -> B :: any()).
-spec(applyListImpl(list(mapFun()), list(any())) -> list(any())).
applyListImpl(Funs, L) ->
[F(X) || X <- L, F <- Funs].
-spec(listAppend(list(A :: any()), list(A :: any())) -> list(A :: any())).
listAppend(A, B) -> lists:append(A, B).
-spec(bindImpl(any(), fun((A :: term()) -> B :: term())) -> any()).
bindImpl(X, F) -> fun() -> (F(X()))() end.
-spec(bindListImpl(list(term()), fun((term()) -> list(term()))) -> list(term())).
bindListImpl(L, F) -> lists:append(lists:map(F, L)).
-spec(pureImpl(any()) -> any()).
pureImpl(X) -> fun() -> X end.
seqio(L) when is_list(L) ->
fun() -> [V() || V <- L] end.
seqio_(L) when is_list(L) ->
fun() -> [V() || V <- L], ok end.
unsafePerformIO(L) -> L().
replApply(F) ->
case is_function(F) andalso (arity(F) == 0) of
true -> F();
false -> F
end.
arity(F) ->
element(2, erlang:fun_info(F, arity)).