Tuesday, March 31, 2020

Learning F# - Step 4 Revisited

I know I should be writing about using F# to connect to a database, but I had to come back to working with files. (Learning the database interaction is taking me longer, and I'll explain why in that post.)

I had an opportunity to use F# at work to essentially "fold" a file at a certain number of characters. (This is a built-in function of *nix OSes, but I was on a Windows box and didn't have my normal set of tooling due to the quarantine.) I needed to read in a file as a string and break it into lines every 170 characters. The mechanism I posted earlier for reading files worked, but it wasn't doing exactly what I needed.

To suit my need, I found the ReadAllText method on the File object in the System.IO package. Below is the code that I put together:

open System.IO

let fileName = fsi.CommandLineArgs.[1]

let fileContents = File.ReadAllText(fileName)

let newString = ""
for i in 1..(fileContents.Length) do
    if i % 170 <> 0 then fileContents.[i-1].ToString()
    else fileContents.[i-1].ToString() + "\n"
    |> printf "%s"
Most of this should look familiar to the code I had in my last post. One big difference is that I actually wrote this as an F# script file (fsx) instead of a straight F# "program." This is why you don't see any actual function definitions in the code. Not being a "real" F# program, the command-line argument handling is different too (fsi.CommandLineArgs). I'll save those items for another post.

The main difference I want to point out is the file operation. In the code above, I read the entire contents of my file into fileContents using the File.ReadAllText method. This change allowed me to work on the contents of the file as a string. That "work" is to iterate over the characters in the file and insert a newline character after every 170 characters.

The fact that I used a FOR loop to do the iteration points to the fact that I have a LOT of learning to do in the functional programming world.

No comments:

Post a Comment