// pipe :: Array (Any -> Any) -> Any -> Any const pipe = fs => x => fs.reduce ((y, f) => f (y), x) // lmap :: (a -> b) -> Array a -> Array b const lmap = f => xs => xs.map (f) // append :: a -> Array a -> Array a const append = x => xs => [...xs, x] // pure :: b -> Future a b const pure = x => l => r => r (x) // then :: (b -> Future a c) -> Future a b -> Future a c const then = f => m => l => r => m (l) (x => f (x) (l) (r)) // fmap :: (b -> c) -> Future a b -> Future a c const fmap = f => then (x => pure (f (x))) // all :: Array (Future a b) -> Future a (Array b) // -- Note: This implementation resolves things in sequence for brevity. const all = ms => ms.reduce ((mxs, mx) => then (x => fmap (append (x)) (mxs)) (mx), pure ([])) const filesystem = require ('fs') const path = require ('path') // readFile :: String -> String -> Future Error String const readFile = encoding => filename => l => r => { filesystem.readFile (filename, encoding, (e, contents) => { if (e) l (e) else r (contents) }) } // readText :: String -> Future Error String const readText = readFile ('utf8') // lines :: String -> Array String const lines = s => s.split ('\n') // unlines :: Array String -> String const unlines = ss => ss.join ('\n') //concatFiles :: (String -> String) -> Future Error String const concatFiles = path => pipe ([ path , readText , fmap (lines) , fmap (lmap (path)) , fmap (lmap (readText)) , then (all) , fmap (unlines) ]) ('index.txt') const main = () => { concatFiles (x => path.resolve (process.argv[2], x)) (e => { process.stderr.write(e.message); process.exit(1) }) (x => { process.stdout.write(x); process.exit(0) }) } main()