Программная запятая через parse_transform
do([Monad ||
A <- foo(),
B <- bar(A, dog),
B
]).
Monad:'>>='(
foo(),
fun (A) -> Monad:'>>='(
bar(A, dog),
fun (B) -> B end)
end).
do
a <- foo
b <- bar a dog
foo >>= \a ->
bar a dog >>= \b -> b
return(X) -> {just, X}.
fail(_X) -> nothing.
do([erlmonads_maybe ||
Num <- get_number(),
erlmonads_plus:guard(erlmonads_maybe, is_number(Num)),
processing_number(Num),
return(Num)
])
Варианты обработки ошибов
ErrGuard = erlmonads_plus:guard(erlmonads_error, _, _),
Res = do([erlmonads_error||
Connection <- amqp_connection:start(AMQP_params),
Channel <- amqp_connection:open_channel(Connection),
ConnectionRef <- return(erlang:monitor(process, Connection)),
ChannelRef <- return(erlang:monitor(process, Channel)),
ErrGuard(
'exchange.declare_ok' =:= element(1, amqp_channel:call(Channel, EDeclareCmd)),
"Could not declare exchange"),
ErrGuard(
'queue.declare_ok' =:= element(1, amqp_channel:call(Channel, QDeclareCmd)),
"Could not declare queue"),
ErrGuard(
'queue.bind_ok' =:= element(1, amqp_channel:call(Channel, BindCmd)),
"Could not bind queue to exchange"),
ErrGuard(
'basic.consume_ok' =:= element(1, amqp_channel:call(Channel, ConsumeCmd)),
"Could not consume"),
return(#state{
connection=Connection,
channel=Channel,
connection_ref=ConnectionRef,
channel_ref=ChannelRef}
)]),
Пример реализации вычисления факториала
fact_rec(0) ->
do([erlmonads_state ||
Acc <- get(),
return(Acc)
]);
fact_rec(N) ->
do([erlmonads_state ||
Acc <- get(),
put(Acc * N),
fact_rec(N - 1)
]).
fact(N) ->
erlmonads_state:eval(
fact_rec(N),
1
).
Пример реализации вычисления факториала
fact_rec :: Int -> State Int Int
fact_rec 0 = do
acc <- get
return acc
fact_rec n = do
acc <- get
put (acc * n)
fact_rec (n - 1)
Пример реализации вычисления чисел фибоначчи
-import(erlmonads_state, [
eval/2, modify/1,
sequence/1, exec/2
]).
fib_m_step() ->
modify(fun ({X, Y}) -> {Y, X+Y} end).
fib(N) ->
{A, _} = exec(
sequence(
lists:duplicate(N, fib_m_step())
),
{0, 1}
),
A.
Пример реализации вычисления чисел фибоначчи
fib_m_step :: State (Int, Int) ()
fib_m_step =
modify $ \(a,b) -> (b,a+b)
fib :: Int -> Int
fib n = fst ((execState $
sequence (Data.List.replicate n fib_m_step)
)
(0, 1))
Реализация State-монады через трансформер
State = erlmonads_state_t:new(erlmonads_identity)