Q:

How do I invoke a function value that serves as a parameter on a function? 

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

A:

The issue is that you have defined log :'medium ->'data -> unit. 
You then take the result of deposit |> makeInitialDeposit, which has type string and pipe it into the log function.   The compiler, logically, then infers that 'medium = string. 
If you accept a 'medium argument in your logDeposit function then you simply move that inference along a step, deposit |> makeInitialDeposit is still a string so now 'data = string. 

I think you are struggling though because these functions don't well model your domain and your logging logic is bleeding out into the rest of your code. 
Why does makeInitialDeposit return a string?   
Why does getBalance return a float but insert accepts a Coin list as its balance argument? 
I would start by making a logging function that accepts three arguments:
let logToFile (filePath:string) (formatf : 'data -> string) data =
    use file = new System. IO.StreamWriter(filePath)
    file. WriteLine(formatf data)
    data

It has type filePath : string -> (formatf : 'data -> string) -> (data : 'data) -> data.   It accepts a path to log to, a function that formats something of type 'data as a string and some 'data to log to the file.   Finally, it returns the data argument you supplied unchanged.   That means you can, in principle, insert logging of any arbitrary value in your code anywhere. 
I then set up some functions in the domain like this:
let valueOf = function
    | Nickel         -> 0.05m
    | Dime           -> 0.10m
    | Quarter        -> 0.25m
    | OneDollarBill  -> 1.00m
    | FiveDollarBill -> 5.00m

let totalValue coins =
    coins |> List.fold (fun acc coin -> acc + valueOf coin) 0.0m

let insert coins coin = coin::coins // returns Coin list

let makeInitialDeposit deposit = insert [] deposit // returns Coin list

I can then use these functions, inserting logging at any arbitrary point:
let balance =
    makeInitialDeposit OneDollarBill
    |> logToFile "file.txt" (sprintf "Initial Deposit: %A")
    |> totalValue
    |> logToFile "file2.txt" (sprintf "Balance : $%M")

This approach lets you fit logging around your domain rather than building your domain around logging.