Code like that:
is very error prone, and worse very hard to extend. Just adding another
function application between f(X) and g(X1) requires you to alter all lines
upto the end of the function:
This causes 2*numberoflinestoendoffunction potential error sources;
And this is also not at all a very functional style.
Why not rewriting it like this:
where one chains together the functions. Adding a function invocation in between is as easy as pie.
Another solution might be using the state monad, wich was
built for dealing with this kind of functional composition.
blah(X) ->
X1 = f(X),
X2 = g(X1),
X3 = h(X2),
i(X3).
is very error prone, and worse very hard to extend. Just adding another
function application between f(X) and g(X1) requires you to alter all lines
upto the end of the function:
blah(X) ->
X1 = f(X),
X2 = j(X1)
X3 = g(X2),
X4 = h(X3),
i(X4).
This causes 2*numberoflinestoendoffunction potential error sources;
And this is also not at all a very functional style.
Why not rewriting it like this:
blah(X) ->
(chain([
f,
g,
h,
i
]))(X).
where one chains together the functions. Adding a function invocation in between is as easy as pie.
chain(FunList) ->
lists:foldl(
fun combine/2,
fun id/1,
FunList).
id(X) -> X.
combine(F,G) ->
RF = to_local_function(F),
RG = to_local_function(G),
fun(X) ->
RF(RG(X))
end.
to_local_function(F) ->
case F of
{FM, FF} -> F;
_ when is_atom(F) -> {?MODULE, F}
end.
Another solution might be using the state monad, wich was
built for dealing with this kind of functional composition.
Comments