F # Implicitly-general parameter of a function in expressions with different types

I have a utility function that combines error message logging (including string formatting) with raising an exception (either using an raiseexisting exception or calling failwithusing a formatted error message similar to the logAndFailWithf function below (although it actually uses a logging framework, not writing to a text file):

let logAndFailWithf exOpt =
    let logFile = new StreamWriter("log.txt")
    Printf.ksprintf <| fun message -> 
        try match exOpt with
            | Some ex -> 
                logFile.WriteLine("{0}\r\n{1}", message, ex)
                raise <| Exception(message, ex)
            | None -> 
                logFile.WriteLine(message)
                failwith message
        finally logFile.Close()

val logAndFailWithf : exOpt:#exn option -> (Printf.StringFormat<'b,'c> -> 'b)

This function works fine if called directly, as in this simple example:

let s = "123x"
let x = try Int32.Parse s
        with | ex -> logAndFailWithf (Some ex) "Failed to parse string s: %s" s

System.Exception: Failed to parse string s: "123x" ---> 
    System.FormatException: Input string was not in a correct format.
    at System.Number.StringToNumber(String str, NumberStyles options, 
    NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
    at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)

However, in a real scenario, the logging function is passed to another function that uses it to record and throw whenever it encounters this exception, as shown below:

let exmaple param1 param2 (log: exn option -> Printf.StringFormat<_,_> -> _) =
    let x = try Int32.Parse param1
            with | ex -> log (Some ex) "Failed to parse param1: \"%s\"" param1

    let y = try Int64.Parse param2
            with | ex -> log (Some ex) "Failed to parse param2: \"%s\"" param2

    printfn "Successfully Parsed Parameters:  param1 = %d; param2 = %d" x y

let binding (let y = ...) :

error FS0001: This expression was expected to have type
    'int64'    
but here has type
    'int'

, , ( int64 y int x), log, logAndFailWithf , .

, ?

+4

Source: https://habr.com/ru/post/1683437/


All Articles