How do I invoke a function value that serves as a parameter on a function?
Specifically, my goal is to leverage a parameter of a function in which the parameter is actually a function.
In my case, I am trying to implement an interface for logging data.
Here's my code:
let logToFile (filePath:string) (message:string) =
let file = new System.IO.StreamWriter(filePath)
file.WriteLine(message)
file.Close()
let makeInitialDeposit deposit =
let balance = deposit |> insert []
sprintf "Deposited: %f" balance
let logDeposit deposit (log:'medium ->'data -> unit) =
deposit |> makeInitialDeposit
|> log
Note the following function:
let logDeposit deposit (log:'medium ->'data -> unit) =
deposit |> makeInitialDeposit
|> log
I get a compile error on the log function:
This construct causes code to be less generic than indicated by the type annotations. The type variable 'medium has been constrained to be type 'string'.
I understand that makeInitialDeposit returns string. However, that string type is mapped to the generic type 'data. Hence, a generic can be of any type right?
I then tried supplying the medium (i.e. file) argument:
let logDeposit deposit (log:'medium ->'data -> unit) medium =
deposit |> makeInitialDeposit
|> log medium
Then my error got updated to:
This construct causes code to be less generic than indicated by the type annotations. The type variable 'data has been constrained to be type 'string'.
My Goal
Ultimately, I just want to have an interface called log and pass in an implementation of that interface (i.e. logToFile).
Any guidance on how I should interpret the compile error based on my initial interpretation?
Insert function dependencies
let getBalance coins =
coins |> List.fold (fun acc d -> match d with
| Nickel -> acc + 0.05
| Dime -> acc + 0.10
| Quarter -> acc + 0.25
| OneDollarBill -> acc + 1.00
| FiveDollarBill -> acc + 5.00) 0.00
let insert balance coin =
coin::balance |> getBalance