As part of a simple challenge I am to write a couple of simple statistical functions by scratch and I'm trying to write them in the most "idiomatic F#" way possible. I am fairly new to Functional Programming so I'm looking to learn how to create simple stuff from the start.
Here's what I have so far:
let mean (x : float list) : float =
(List.sum x) / (float (List.length x))
let variance (x : float list) : float =
x
|> List.map (fun a -> pown (a - (mean x)) 2)
|> mean
let stdDev =
variance >> Math.Sqrt
I like how the stdDev
function is defined using composition but I get the feeling there might be some prettier, more idiomatic way of defining the first two.
Any suggestions?
Your code is perfectly fine and idiomatic.
Personally, I prefer one liners whenever possible. That way I can align the code to highlight similarities and differences between the functions. Patterns just jump at you that way.
let mean x = (Seq.sum x) / (float (Seq.length x))
let variance x = let m = mean x
x |> Seq.map (fun a -> pown (a - m) 2) |> mean
let stdDev x = x |> variance |> Math.Sqrt
I also prefer seq
to list
because they can be used with lists, arrays, sets or any other sequence.
do [| 5. ; 6. ; 7. |] |> stdDev |> printfn "%A"
do [ 5. ; 6. ; 7. ] |> stdDev |> printfn "%A"
Set [ 5. ; 6. ; 7. ] |> stdDev |> printfn "%A"
seq [ 5. ; 6. ; 7. ] |> stdDev |> printfn "%A"
seq { 5. .. 7. } |> stdDev |> printfn "%A"
In F# is better to avoid the >>
composition operator and use the pipe |>
instead.
There are many issues with composing functions like that. For instance the above code would not be possible (using different types like lists and arrays).