I'm writing a file processor in JavaScript (Node.js). Simplified pseudo code as below. For each line in file it prints to output and if the line is an include indicator it recursively handle the included file.
function fileProcessor (file) {
// read lines from file
lines.forEach( function (line) {
// #1 - include processor:
if line matches "#include includefile"
fileProcessor(includefile);
// #2 - output processor:
// write line to output
});
}
The next step I want to improve its design by decoupling the file processor and line processor. I'm familiar with OO, it should look like below class diagram. But now I want to try it in FP way.

Define a function that returns the fileProcessor, which line processors are applied.
var fileProcessorGen = function (lineProcessors) {
return function (file) {
// read lines from file
lines.forEach( function (line) {
lineProcessors.forEach( function (processor) {
processor.call(this, line);
});
});
};
};
My purpose is to achieve separation of concerns. In the example there are only two line processors but actually there will be more. And the caller will pick some line processors into use on its purpose. So I don't hard code them into file processor or any line processors.
var fileProcessor = fileProcessorGen([includeProcessor, outputProcessor]);
Now my problem is how can I call fileProcessor (which is partial application) inside my include processor?
function includeProcessor(line) {
if line matches "#include includefile"
fileProcessor(includefile); // <--- how to get fileProcessor ?
};
function outputProcessor(line) {
// write line to output
}
Maybe I have to pass the fileProcessor as argument into includeProcessor, but how?
function includeProcessor(line, fileProcessor) {
if line matches "#include includefile"
fileProcessor(includefile);
};
var fileProcessorGen = function (lineProcessors) {
return function (file) {
// read lines from file
lines.forEach( function (line) {
lineProcessors.forEach( function (processor) {
processor.call(this, line, ???); // <-- how to pass the parameter?
});
});
};
};