A two hour hack and write session:
A first go at a computation expression. Based on a simple coding challenge that was much harder in interview than at home, I decided to go a step further and see how quickly I could grok enough of computation expressions to make one work. Below is the version 1. The short explanation is define a function that takes a value AND another function as a parameter and utilise the latter function in it’s return values. In the type below this goes a bit further because we have members that can be used in various ways. I’ve scratched the surface as I wanted to ensure I disposed of my streamReader each time. Next stage, multithreads!
let filePath = new System.IO.DirectoryInfo(@"c:\dropbox") let countWords(x: string) = x.Split(',').Length type fileStream() = member this.Using( x : FileInfo, c: string -> int)= use streamReader = x.OpenText().ReadToEndAsync() streamReader.Result |> c member this.Return(x : string ) = countWords x let str = fileStream() let WordCount = filePath.EnumerateFiles("*.csv", SearchOption.AllDirectories) |> Seq.sumBy(fun x -> str.Using(x, countWords) ) printfn "%i" WordCount
These are considered quite hard, unless your already very skilled. However, as I look at this, the hard part is getting the syntax right as conceptually it’s not quite as bad as all that. UPDATE – A few beers later. I decided to add something more visual to this demo, this of course after a few beers with my better half.
open System.IO open Microsoft.FSharp open FSharp.Charting open System.Windows.Forms open System.Drawing let filePath = new System.IO.DirectoryInfo(@"e:\Dropbox") let wordCount ( x: string) = x.Split(',').Length type streamRead() = member this.Using( file : FileInfo, c: string -> int) = use x = file.OpenText() x.ReadToEnd() |> c let stream = streamRead() let FileTotal = filePath.EnumerateFiles("*.csv", SearchOption.AllDirectories) |> Seq.map ( fun x -> stream.Using(x, wordCount) ) |> Chart.Line let form = new Form(Visible = true, TopMost = true, Width = 700, Height = 500) form.Controls.Add(new ChartTypes.ChartControl(FileTotal, Dock = DockStyle.Fill)) Application.Run(form)