Function composition builds a new function by applying one function to the result of another. In Haskell, the (.) operator applies its right-hand function first, then its left-hand function: (.) f g x = f (g x). This chains partially applied functions while keeping definitions concise. section 8.3
Composing CSV output
A CSV writer can compose text conversion, row joining, line joining, and file output: writeCsv path = TIO.writeFile path . T.intercalate "\n" . toFileContent. Calling the resulting function supplies a Csv value, which flows through each transformation before being written. section 8.3
Composition supports several practical patterns:
- Treat functions as values: pass them to functions, return them, store them in data structures, or compute new functions from them. section 8.3
- Build a function from a list of functions by folding with (.) and id. section 8.3
- Use composition alongside let bindings or the dollar operator; the design remains a description of results flowing between functions. section 8.3
Listing 8.8 Functions to write CSV values to files
toFileContent :: Csv -> [T.Text]
toFileContent Csv {..} =
let rows = L.map (L.map dataFieldToText)
$ L.transpose csvColumns #1
in L.map (T.intercalate ",") $ #2
M.maybe rows (: rows) csvHeader #3
writeCsv :: FilePath -> Csv -> IO ()
writeCsv path = TIO.writeFile path .
T.intercalate "\n" . toFileContent #4
Inspect the complete CSV file-writing pipeline, including field conversion, row and line intercalation, optional headers, and composed file output. section 8.3










