F# is a powerful language. When you start with functional programming you find it hard to write truly functional code. After all you have thought in imperative terms like for, foreach, while, do while, …. Mark Pearl has provided a little sample how to parse a text file with F# to count the error and warnings inside it. I think it can be more functional. Here is my try:
#light
open System
open System.IO
let lineSequence(file) =
let reader = File.OpenText(file)
Seq.unfold(fun line ->
if line = null then
reader.Close()
None
else
Some(line,reader.ReadLine())) (reader.ReadLine())
let CalculateStats(lines:seq<string>) =
lines |> Seq.fold(
fun (lineCount,info,warn,error) line -> match line with
| _ when line.Contains("info") -> (lineCount+1, info+1, warn, error)
| _ when line.Contains("_warning_") -> (lineCount+1, info , warn+1, error)
| _ when line.Contains("*ERROR*") -> (lineCount+1, info , warn , error+1)
| _ -> (lineCount+1, info , warn , error )) (0,0,0,0)
let lineCount,info,warn,errors = @"C:\Source\fsharpparser\data.txt" |> lineSequence |> CalculateStats
printf "LineCount: %d, Got %d infos, %d warnings, %d errors" lineCount info warn errors
Console.ReadLine() |> ignore
In contrast to Marks version I do read the file line by line instead of reading the whole file at once (lazy evaluation is key) and I do check not only for errors and warnings. I thought that info's might also be part of the log file so I do count them as well. I must admit that it takes some time to get it right but I am like Mark still learning how to employ F# for practical purposes.