
Habr├й рдкрд░, рдЖрдк рдХрдИ рдкреНрд░рдХрд╛рд╢рдиреЛрдВ рдХреЛ рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рджреЛрдиреЛрдВ рд╕рд╛рдзреБрдУрдВ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдЙрдирдХреЗ рдЖрд╡реЗрджрди рдХреЗ рдЕрднреНрдпрд╛рд╕ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рддреЗ рд╣реИрдВред рдЗрдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЗрдЦ рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИрдВред рдореИрдВ nth рд╕рдордп рдХреЗ рд▓рд┐рдП рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ред рдЖрдЬ рд╣рдо рдХреБрдЫ Erlang рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ, рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдзреБрдУрдВ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ, рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЖрдВрд╢рд┐рдХ рдЙрдкрдпреЛрдЧ рдФрд░ erlando рд╕реЗ рд╡рд╛рдХреНрдпрдЧрдд рдЪреАрдиреА - RabbitMQ рдЯреАрдо рд╕реЗ рдПрдХ рд╢рд╛рдВрдд рдкреБрд╕реНрддрдХрд╛рд▓рдпред
рдкрд░рд┐рдЪрдп
рдПрд░реНрд▓реИрдВрдЧ рдореЗрдВ рдЕрд╕реНрдерд┐рд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдИ рд╕рдиреНрдпрд╛рд╕реА рдирд╣реАрдВред рд▓реЗрдХрд┐рди рднрд╛рд╖рд╛ рдореЗрдВ parse_transform рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдФрд░ erlando рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЕрднреА рднреА рдЗрд░рдбрд╛рдВрдЧ рдореЗрдВ рдордареЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред
рдХрд╣рд╛рдиреА рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкреНрд░рддрд┐рд░рдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдореИрдВрдиреЗ рд╕рдВрдпреЛрдЧ рд╕реЗ рдмрд╛рдд рдирд╣реАрдВ рдХреАред рдЗрдореНрдпреВрдирд┐рдЯреА рд▓рдЧрднрдЧ рд╣рд░ рдЬрдЧрд╣ рдФрд░ рд╣рдореЗрд╢рд╛ рд╣реЛрддреА рд╣реИ - рдПрд░реНрд▓реИрдВрдЧ рдХреЗ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХред рдХрд╛рд░реНрдпреЛрдВ рдХреА рдкреНрд░рддрд┐рд░рдХреНрд╖рд╛ рдФрд░ рд╢реБрджреНрдзрддрд╛ рдЖрдкрдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡рд┐рдХрд╛рд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╕реЗ рдбрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд╛рд╡рд╛ рдпрд╛ рдкрд╛рдЗрдерди рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдПрд░рд▓реИрдВрдЧ рдХреЗ рдирдП рд▓реЛрдЧ, рдПрд░реНрд▓реИрдВрдЧ рдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд╕рдордЭрдирд╛ рдФрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрджрд┐ рдЖрдк рдПрд░рд▓рдВрдЧ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВред рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдиреЗ рдПрд░рд▓рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЙрдиреНрд╣реЛрдВрдиреЗ рд╢рд╛рдпрдж рдЗрд╕рдХреА рдЕрд╕рд╛рдорд╛рдиреНрдпрддрд╛ рдФрд░ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ред рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВрдиреЗ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдПрдХрддреНрд░ рдХреА рд╣реИ рдФрд░ "рдЕрдЬреАрдм" рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд░реЗрдЯрд┐рдВрдЧ рдХрд╛ рдиреЗрддреГрддреНрд╡ рдХрд░рддрд╛ рд╣реИред
Erlando
рдПрд░реНрд▓реИрдВрдбреЛ рдПрдХ рдПрд░рд▓реИрдВрдЧ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реЗрдЯ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рджреЗ рд░рд╣рд╛ рд╣реИ:
- рдпреЛрдЬрдирд╛ рдЬреИрд╕реЗ рдХрдЯреМрддреА рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЖрдВрд╢рд┐рдХ рдЙрдкрдпреЛрдЧ / рдХрд░реА
- рд╣рд╛рд╕реНрдХреЗрд▓ рдЬреИрд╕реА рдзрд╛рд░рдгрд╛рдПрдБ
- import-as - рдЕрдиреНрдп рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрдЯрд┐рдХ рд╢реБрдЧрд░ред
рдиреЛрдЯ: рдореИрдВрдиреЗ рдореИрдереНрдпреВ рд╕реИрдХрдореИрди рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рд╕реЗ рдПрд░рд▓реИрдВрдбреЛ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рд▓рд┐рдпрд╛, рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдореЗрд░реЗ рдХреЛрдб рдФрд░ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдкрддрд▓рд╛ рдХрд┐рдпрд╛ред
рд╕рд╛рд░ рдХрдЯ
рд╕реАрдзреЗ рдмрд┐рдВрджреБ рдкрд░ рдЬрд╛рдПрдВред рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдХрдИ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
info_all(VHostPath, Items) -> map(VHostPath, fun (Q) -> info(Q, Items) end). backing_queue_timeout(State = #q{ backing_queue = BQ }) -> run_backing_queue( BQ, fun (M, BQS) -> M:timeout(BQS) end, State). reset_msg_expiry_fun(TTL) -> fun (MsgProps) -> MsgProps #message_properties{ expiry = calculate_msg_expiry(TTL)} end.
рдЗрди рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рд░рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдПрдХ рдЖрдВрд╢рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЙрд▓ рд╕реЗ рдкрд╣рд▓реЗ рдХреБрдЫ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓реЗрдЧрд╛ред рд▓рдЪреАрд▓реЗрдкрди рдХреЗ рд╕рд╛рде, рдпреЗ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рд╢реЛрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдереЛрдбрд╝рд╛ рдмрджрд▓рдХрд░ - рдХрдЯ рджрд░реНрдЬ рдХрд░рдХреЗ - рдЖрдк рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реБрдзрд╛рд░ рд╕рдХрддреЗ рд╣реИрдВред
рдорд╛рди _
- _ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
- рдХрдЯ рдЖрдкрдХреЛ рдмрд╛рд╣рд░ рдХреЗ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ
- рдпрджрд┐ рдпрд╣ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдмрд╛рд╣рд░ рд╣реИ, рддреЛ рдпрд╣ рдЙрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдмрди рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╕реНрдерд┐рдд рд╣реИ
- рдПрдХ рд╣реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рднреАрддрд░ _ рдХреЗ рдХрдИ рдЙрдкрдпреЛрдЧ рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдХрдИ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ
- рдХрдЯ рдХреНрд▓реЛрдЬрд░ (рдлрди) рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдирд╣реАрдВ рд╣реИ
- рдХрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдПрдмреНрд╕рдЯреНрд░реИрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдЯ рдЗрди _ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдХрдЯ рдХреЗрд╡рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдирд┐рдХрдЯрддрдо рд╕реНрддрд░ рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдиреЗрд╕реНрдЯреЗрдб рдХрдЯ рдирд┐рд╖рд┐рджреНрдз рдирд╣реАрдВ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП list_to_binary([1, 2, math:pow(2, _)]).
list_to_binary([1, 2, fun (X) -> math:pow(2, X) end]).
рд╣реИ list_to_binary([1, 2, fun (X) -> math:pow(2, X) end]).
рд▓реЗрдХрд┐рди fun (X) -> list_to_binary([1, 2, math:pow(2, X)]) end.
ред
рдпрд╣ рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд▓рдЧрддрд╛ рд╣реИ, рдЪрд▓реЛ рдХрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВ:
info_all(VHostPath, Items) -> map(VHostPath, fun (Q) -> info(Q, Items) end). info_all(VHostPath, Items) -> map(VHostPath, info(_, Items)).
backing_queue_timeout(State = #q{ backing_queue = BQ }) -> run_backing_queue( BQ, fun (M, BQS) -> M:timeout(BQS) end, State). backing_queue_timeout(State = #q{backing_queue = BQ}) -> run_backing_queue(BQ, _:timeout(_), State).
reset_msg_expiry_fun(TTL) -> fun (MsgProps) -> MsgProps #message_properties { expiry = calculate_msg_expiry(TTL) } end. reset_msg_expiry_fun(TTL) -> _ #message_properties { expiry = calculate_msg_expiry(TTL) }.
рддрд░реНрдХ рдЧрдгрдирд╛ рдЖрджреЗрд╢
рдЙрд╕ рдХреНрд░рдо рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
f1(_, _) -> io:format("in f1~n"). test() -> F = f1(io:format("test line 1~n"), _), F(io:format("test line 2~n")).
рдЪреВрдВрдХрд┐ рдХрдЯ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдкрд╣рд▓реЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ:
test line 2 test line 1 in f1
рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдФрд░ рдХреЛрдб рдХреЗ рдкреИрдЯрд░реНрди рдореЗрдВ рдЕрдореВрд░реНрддрддрд╛ рдХрд╛рдЯреЗрдВ
- tuples
F = {_, 3}, {a, 3} = F(a).
- рд╕реВрдЪрд┐рдпрд╛рдБ
dbl_cons(List) -> [_, _ | List]. test() -> F = dbl_cons([33]), [7, 8, 33] = F(7, 8).
- рдЕрднрд┐рд▓реЗрдЦ
-record(vector, { x, y, z }). test() -> GetZ = _#vector.z, 7 = GetZ(#vector { z = 7 }), SetX = _#vector{x = _}, V = #vector{ x = 5, y = 4 } = SetX(#vector{ y = 4 }, 5).
- рдорд╛рдорд▓реЗ
F = case _ of N when is_integer(N) -> N + N; N -> N end, 10 = F(5), ok = F(ok).
- рдореИрдкреНрд╕
test() -> GetZ = maps:get(z, _), 7 = GetZ(#{ z => 7 }), SetX = _#{x => _}, V = #{ x := 5, y := 4 } = SetX(#{ y => 4 }, 5).
- рдорд┐рд▓рд╛рди рд╕реВрдЪреА рдФрд░ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг
test_cut_comprehensions() -> F = << <<(1 + (X*2))>> || _ <- _, X <- _ >>,
рдкреЗрд╢реЗрд╡рд░реЛрдВ
- рдХреЛрдб рдЫреЛрдЯрд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред
- рдХреЛрдб рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИред
- рдорд╕реНрддреА рд╕реЗ рд╢реЛрд░ рдордЪ рдЧрдпрд╛ред
- Erlang рдореЗрдВ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, Get / Set рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред
рд╡рд┐рдкрдХреНрд╖
- рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдХреЛ рдХрдо рдХрд░рддреЗ рд╣реБрдП, рдЕрдиреБрднрд╡реА рдПрд░реНрд▓рд╛рдВрдЧ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдмрдврд╝рд╛ рджреА рдЧрдИ рд╣реИред рдЕрдм рдЯреАрдо рдХреЛ рдХрдЯреМрддреА рдХреЛ рд╕рдордЭрдиреЗ рдФрд░ рдПрдХ рдФрд░ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдВрдХреЗрддрди
рд╢реАрддрд▓ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рдПрдХ рд╕рдВрдЧрдгрдирд╛ рдмрдВрдзрди рд╣реИред Erlang рдореЗрдВ рдЖрд▓рд╕реА рдЧрдгрдирд╛ рдореЙрдбрд▓ рдирд╣реАрдВ рд╣реИред рдЖрдЗрдП рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдпрджрд┐ рдПрд░реНрд▓реИрдВрдЧ рд╣рд╛рд╕реНрдХреЗрд▓ рдХреА рддрд░рд╣ рдЖрд▓рд╕реА рдереЗ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛
my_function() -> A = foo(), B = bar(A, dog), ok.
рдирд┐рд╖реНрдкрд╛рджрди рдЖрджреЗрд╢ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдХреЗ рдЧрдгрдирд╛рдУрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред
my_function() -> A = foo(), comma(), B = bar(A, dog), comma(), ok.
рд░реВрдкрд╛рдВрддрд░рдг рдЬрд╛рд░реА рд░рдЦреЗрдВ:
my_function() -> comma(foo(), fun (A) -> comma(bar(A, dog), fun (B) -> ok end)).
рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо / 2 рдПрдХ рдореБрд╣рд╛рд╡рд░реЗрджрд╛рд░ рдХрд╛рд░реНрдп рд╣реИ >>=/2
ред рд╕рдиреНрдпрд╛рд╕реА рдХреЛ рдХреЗрд╡рд▓ рддреАрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ: >>=/2
, return/1
рдФрд░ fail/1
ред
рд╕рдмрдХреБрдЫ рдареАрдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╕рд┐рд░реНрдл рднрдпрд╛рдирдХ рд╣реИред рд╣рдо erlando
рд╕реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред
do([Monad || A <- foo(), B <- bar(A, dog), ok]).
рдореЛрдирд╛рдбреНрд╕ рдХреЗ рдкреНрд░рдХрд╛рд░
рдЪреВрдВрдХрд┐ рдбреЛ-рдмреНрд▓реЙрдХ рдХреЛ рдорд╛рдирдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдбреЛ-рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░, рдХреЙрд▓ return/1
рдФрд░ fail/1
рдХреЛ Monad:return/1
рдФрд░ Monad:fail/1
рдХреНрд░рдорд╢рдГ рдкрд░рд┐рдирд┐рдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд╣рдЪрд╛рди-рдЗрдХрд╛рдИред
рд╕рдорд╛рди рдореЛрдирд╛рдб рд╕рдмрд╕реЗ рд╕рд░рд▓ рдореЛрдирд╛рдб рд╣реИ рдЬреЛ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ рдФрд░ рдЧрдгрдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд┐рдпрдВрддреНрд░рдг рдореЗрдВ рднрд╛рдЧ рдирд╣реАрдВ рд▓реЗрддрд╛ рд╣реИред рдЗрд╕реЗ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рд╕рд╛рде рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓рд┐рдВрдХрд┐рдВрдЧ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХрд░рддрд╛ рд╣реИ - рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЙрдорд╛ред
рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐-рдЗрдХрд╛рдИред
рд▓рд╛рдкрддрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдЧрдгрдирд╛ рдХрд╛ рдореЛрдирд╛рдбред рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рдкрд░рд┐рдХрд▓рд┐рдд рдЧрдгрдирд╛ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рдирд╛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд╣реИ, рдПрдХ рдЕрдиреБрдкрд╕реНрдерд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЧрдИ рдЧрдгрдирд╛ рд╕реЗ рдЬреЛрдбрд╝рдирд╛ рдПрдХ рдЕрдиреБрдкрд╕реНрдерд┐рдд рдкрд░рд┐рдгрд╛рдо рд╣реИред
рд╢рд╛рдпрдж_рдо рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
if_safe_div_zero(X, Y, Fun) -> do([maybe_m || Result <- case Y == 0 of true -> fail("Cannot divide by zero"); false -> return(X / Y) end, return(Fun(Result))]).
рдпрджрд┐ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рддреЛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рд░реБрдХ рдЬрд╛рддрд╛ рд╣реИред
{just, 6} = if_safe_div_zero(10, 5, _+4) ## 10/5 = 2 -> 2+4 -> 6 nothing = if_safe_div_zero(10, 0, _+4)
рддреНрд░реБрдЯрд┐-рдЗрдХрд╛рдИред
IF_m рдХреЗ рд╕рдорд╛рди, рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд╕рд╛рдеред рдХрднреА-рдХрднреА рдЗрд╕реЗ рджреБрд░реНрдШрдЯрдирд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдиреЗ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕ рд╕рдордп рд╣реЛрдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЗрд╕ рд╕реЗ рд╕реАрдврд╝рд┐рдпрд╛рдВ рдЕрдХреНрд╕рд░ рдХреЛрдб рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпреЗ:
write_file(Path, Data, Modes) -> Modes1 = [binary, write | (Modes -- [binary, write])], case make_binary(Data) of Bin when is_binary(Bin) -> case file:open(Path, Modes1) of {ok, Hdl} -> case file:write(Hdl, Bin) of ok -> case file:sync(Hdl) of ok -> file:close(Hdl); {error, _} = E -> file:close(Hdl), E end; {error, _} = E -> file:close(Hdl), E end; {error, _} = E -> E end; {error, _} = E -> E end.
make_binary(Bin) when is_binary(Bin) -> Bin; make_binary(List) -> try iolist_to_binary(List) catch error:Reason -> {error, Reason} end.
рдпрд╣ рдкрдврд╝рдирд╛ рдЕрдкреНрд░рд┐рдп рд╣реИ, рдЬреЗрдПрд╕ рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдиреВрдбрд▓реНрд╕ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред Error_m рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИ:
write_file(Path, Data, Modes) -> Modes1 = [binary, write | (Modes -- [binary, write])], do([error_m || Bin <- make_binary(Data), Hdl <- file:open(Path, Modes1), Result <- return(do([error_m || file:write(Hdl, Bin), file:sync(Hdl)])), file:close(Hdl), Result]). make_binary(Bin) when is_binary(Bin) -> error_m:return(Bin); make_binary(List) -> try error_m:return(iolist_to_binary(List)) catch error:Reason -> error_m:fail(Reason) end.
- рд╕реВрдЪреА-рдЗрдХрд╛рдИред
рдорд╛рди рдПрдХ рд╕реВрдЪреА рдХреА рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рдЬрд╛ рд╕рдХрдиреЗ рд╡рд╛рд▓реА рд╕реВрдЪреА рд╣реИред рдпрджрд┐ рдПрдХ рдЧрдгрдирд╛ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рддреЛ рджреВрд╕рд░реА рдЧрдгрдирд╛ рдкрд╣рд▓реЗ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдо (рджреВрд╕рд░реА рдЧрдгрдирд╛) рдХреЛ рдПрдХ рд╕реВрдЪреА рдореЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреНрд▓рд╛рд╕рд┐рдХ рдкрд╛рдпрдерд╛рдЧреЙрд░рд┐рдпрди рдЯреНрд░рд╛рдЗрдПрд▓реНрд╕ рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рд╣рдо рдЙрдиреНрд╣реЗрдВ рдмрд┐рдирд╛ рдореЛрдирд╛рдб рдХреЗ рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
P = [{X, Y, Z} || Z <- lists:seq(1,20), X <- lists:seq(1,Z), Y <- lists:seq(X,Z), math:pow(X,2) + math:pow(Y,2) == math:pow(Z,2)].
рдХреЗрд╡рд▓ list_m рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдЪреАрдЬрд╝:
P = do([list_m || Z <- lists:seq(1,20), X <- lists:seq(1,Z), Y <- lists:seq(X,Z), monad_plus:guard(list_m, math:pow(X,2) + math:pow(Y,2) == math:pow(Z,2)), return({X,Y,Z})]).
- рд░рд╛рдЬреНрдп рдЗрдХрд╛рдИред
рд╕реНрдЯреЗрдЯрдлреБрд▓ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рдореЛрдирд╛рдбред
рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдордиреЗ рдЪрд░ рд░рд╛рдЬреНрдп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреА рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреАред рдЕрдХреНрд╕рд░ рдХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
State1 = init(Dimensions), State2 = plant_seeds(SeedCount, State1), {DidFlood, State3} = pour_on_water(WaterVolume, State2), State4 = apply_sunlight(Time, State3), {DidFlood2, State5} = pour_on_water(WaterVolume, State4), {Crop, State6} = harvest(State5), ...
рдПрдХ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдФрд░ рдХрдЯ-рдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЗрд╕ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рдФрд░ рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
StateT = state_t:new(identity_m), SM = StateT:modify(_), SMR = StateT:modify_and_return(_), StateT:exec( do([StateT || StateT:put(init(Dimensions)), SM(plant_seeds(SeedCount, _)), DidFlood <- SMR(pour_on_water(WaterVolume, _)), SM(apply_sunlight(Time, _)), DidFlood2 <- SMR(pour_on_water(WaterVolume, _)), Crop <- SMR(harvest(_)), ... ]), undefined).
- рдУрдореЗрдЧрд╛ рдЗрдХрд╛рдИред
List_m monad рдХреЗ рд╕рдорд╛рдиред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдорд╛рд░реНрдЧ рддрд┐рд░рдЫреЗ рдмрдирд╛ рд╣реИред
рдЫрд┐рдкреА рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ
рд╢рд╛рдпрдж error_m
рдХреА рдореЗрд░реА рдкрд╕рдВрджреАрджрд╛ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХред рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рддреНрд░реБрдЯрд┐ рдХрд╣рд╛рдВ рд╣реЛрддреА рд╣реИ, рдореЛрдирдб рд╣рдореЗрд╢рд╛ {ok, Result}
рдпрд╛ {error, Reason}
ред рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
do([error_m || Hdl <- file:open(Path, Modes), Data <- file:read(Hdl, BytesToRead), file:write(Hdl, DataToWrite), file:sync(Hdl), file:close(Hdl), file:rename(Path, Path2), file:delete(Path), return(Data)]).
Import_as
рдирд╛рд╢реНрддреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ import_as рдЪреАрдиреА рд╣реИред -Import / 2 рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдп рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рджреВрд╕рд░реЛрдВ рд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЖрдкрдХреЛ рдЖрдпрд╛рддрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред Import_as рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ:
-import_as({my_mod, [{size/1, m_size}]}) -import_as({my_other_mod, [{size/1, o_size}]})
рдЗрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдХреНрд░рдорд╢рдГ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдерд╛рдиреАрдп рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
m_size(A) -> my_mod:size(A). o_size(A) -> my_other_mod:size(A).
рдирд┐рд╖реНрдХрд░реНрд╖
рдмреЗрд╢рдХ, рдореЛрдирдбреНрд╕ рдЖрдкрдХреЛ рдЕрдзрд┐рдХ рдЕрднрд┐рд╡реНрдпрдВрдЬрдХ рд╡рд┐рдзрд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдФрд░ рд╕рдордп рдмрдЪрд╛рддреЗ рд╣реИрдВред рджреВрд╕рд░реА рдУрд░, рд╡реЗ рдЕрдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдЯреАрдо рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрдЯрд┐рд▓рддрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
* - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрд░реНрд▓рд╛рдВрдЧ рдореЛрдирд╛рдб рдореЗрдВ рдПрд░рд▓реИрдВрдбреЛ рдХреЗ рдмрд┐рдирд╛ рдореМрдЬреВрдж рд╣реИрдВред рдПрдХ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рднрд╛рд╡ рд░реЗрдЦрд╛рдВрдХрди рдФрд░ рд╕рдВрдЧрдгрдирд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реИред
рдкреБрдирд╢реНрдЪ рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдПрд░рд▓реИрдВрдбреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓реЗрдЦрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЕрднрд┐рд▓реЗрдЦреАрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдореИрдВрдиреЗ рдпрд╣ рд▓реЗрдЦ рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛ред рдлрд┐рд░, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдм рдХреЗ рд░реВрдк рдореЗрдВ, Habr├й рдкрд░ Erlang рдореЗрдВ рднрд┐рдХреНрд╖реБрдУрдВ рдкрд░ рдХреЛрдИ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рдереАред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдпрд╣ рд▓реЗрдЦ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдБ, рднрд▓реЗ рд╣реА рдпрд╣ рд▓реЗрдЦ рдХрд┐рддрдирд╛ рднреА рдЕрдЪреНрдЫрд╛ рдХреНрдпреЛрдВ рди рд╣реЛред
Erlang> = 22 рдореЗрдВ erlando рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдкрдЪрд┐рдд erlang: get_stacktrace / 0 рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдлрд┐рдХреНрд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдореЗрд░реЗ рдХрд╛рдВрдЯреЗ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: https://github.com/Vonmo/erlando/commit/52e23ecedd2b8c13707a11c7f0f14496b5a19c2c2
рдЖрдкрдХреЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!