Expert F# 4.0

Category: Programming
Author: Don Syme, Adam Granicz, Antonio Cisternino
This Month Stack Overflow 1


by anonymous   2019-01-13

Generally it's better to show some example code (even if it doesn't work). In its most simplistic form the following function will do what you want:

open System
open System.IO
let reverseLines f =
  File.ReadAllLines f
  |> Seq.rev

Regarding taking on optional parameters, I believe this should better be done via a CLI library, like Argu, that should handle the other arguments to tac as well.


I just changed the reverse function to Array.rev because that's easier to deal with in this case.

There are two parts to this program, you can see that reverseLines is essentially unchanged. Then in the main we check how many arguments there are and extract the file name into fName. In the second part we call directly File.exists on the file name and if it's true we run reverseLines, and pipe the output into the Console.

You can just run this program as .\lineReverser.exe C:\tmp\FileToBeReversed.txt. In case you are just testing in an fsx file just factor out the main into another function and it will work exactly the same.

Everything else in the first part of the answer still stands, some good books on F# include: Expert F# 4.0, Get Programming with F#. And if you just go through the intro Series parts of fsharpforfunandprofit that will clear up many questions you might have.

module SOAnswers171016
open System
open System.IO

let reverseLines f =
  File.ReadAllLines f
  |> Array.rev

let main argv =
    let fName = //check how many arguments are passed and extract the filename if there is only one argument 
        match argv.Length with
        | 0 -> failwith "Please specify a file name!"
        | 1 -> argv.[0]
        | _ -> failwith "Too many parameters!"  //you could handle the two file parameter case here 

    match File.Exists(fName) with
    | true -> reverseLines fName |> Array.iter Console.WriteLine //we are just piping the reversed lines to the console
    | false -> failwith "File doesn't exist!"

    0 // return an integer exit code