Generalise a definition by selecting a sub-expression of the right-hand side and making this the value of a new argument added to the definition of the function or constant.
The sub-expression becomes the actual parameter at the call sites.
format :: [String] -> [String]
format [] = []
format [x] = [x]
format (x:xs) = (x ++ "\n") : format xs
table = concat . format
|
format :: [a] -> [[a]] -> [[a]]
format sep [] = []
format sep [x] = [x]
format sep (x:xs) = (x ++ sep) : format sep xs
table = concat . format "\n"
|
General comment:
The choice of the position where the argument is added
is not accidental: putting the argument at the
beginning of the argument list means that it can
be added correctly to any partial applications of
the function.
Note that in the Add
Argument refactoring we name the new
parameter at the same level as the definition, whereas here we substitute
the expression at all call sites.
Left to right comment:
In the example shown, a single expression is selected.
It is possible to abstract over a number of
occurrences of the (syntactically) identical
expression by preceding this refactoring by
in a multi-module system, some of the free variables in the selected sub-expression might not be accessible to the call sites in some client modules. Instead of explicitly exporting and/or importing these variables, the refactorer creates an auxiliary function (f_gen, say) in the module containing the definition to represent the sub-expression, and makes it accessible to the client modules. | Right to left comment:
The inverse can be seen as a sequence of simpler
refactorings.
This refactoring has not been implemented yet. |
Left to right conditions:
There are two general conditions on the refactoring,
| Right to left conditions:
The successful specialisation depends upon the
definition of the function to have a particular
form: the particular argument to be removed has to
be a constant parameter: that is, it should appear
unchanged in every recursive call.
The definition of the original function can only be
removed if it is only used in the specialised
form.
|