2
import { pipe } from 'rambda';
function readFile(filePath) { // reading the file return fileContents }
function editFile(fileContents) { // edit the file return newFileContents }
function writeFile(fileContents, filePath) { // write content  }

function manipulateFile(filePath) {
  return writeFile(pipe(readFile, editFile)(filePath))(filePath);
}

is there any way to avoid filePath argument duplication in manipulateFile?

Ideally I would like to pipe it like this. But filePath will be not provided to writeFile

function manipulateFile(filePath) {
  return pipe(
    readFile,
    editFile,
    writeFile
  )(filePath)
}
remtsoy
  • 465
  • 1
  • 3
  • 15

1 Answers1

1

You can use the chain combinator to pass the same argument to multiple nested function calls.

Here is an excerpt from common combinators in JavaScript:

const S_ = f => g => x => f (g (x)) (x)

[...]

Name # Haskell Ramda Sanctuary Signature
chain S_ (=<<) chain chain (a → b → c) → (b → a) → b → c

To make it more obvious how it is relevant here, consider this - your manipulateFile can be re-written as:

function manipulateFile(filePath) {
  const f = writeFile;
  const g = pipe(readFile, editFile);
  const x = filePath;

  return f (g (x)) (x);
}

Which matches exactly with the S_ body and can thus be represented as S_(f)(g)(x).

Using the Rambda chain you can use:

import { pipe, chain } from 'ramda';
function readFile(filePath) { // reading the file return fileContents }
function editFile(fileContents) { // edit the file return newFileContents }
function writeFile(fileContents, filePath) { // write content  }

function manipulateFile(filePath) {
  return chain(writeFile, pipe(readFile, editFile))(filePath);
}

or reduce it to point-free:

const manipulateFile = chain(writeFile, pipe(readFile, editFile));

It seems that the Rambda chain does not work the same way as Ramda does.

VLAZ
  • 26,331
  • 9
  • 49
  • 67