This is one of the reasons why I find the point-free style problematic. It makes it difficult to use standard language constructs like try .. with
(or standard loops and other F# features) and you need to replace them with custom combinators. In this case, you could define combinator tryWith2
that wraps a two-argument function in an exception handler:
let tryWith2 f h a b =
try f a b // Call the function with two arguments
with e ->
// Try running the error handler with the exception
match h e with
| Some g -> g a b // Error handler provided another function
| _ -> reraise() // Error was not handled - reraise
Then you could write the function in a point-free style like this (the error handling is still not-point-free, but I do not want to make this too silly :-))
let divide2 =
tryWith2 (/) (function
| :? System.DivideByZeroException -> Some(fun _ _ -> 42)
| _ -> None)
let x1 = divide2 5 0 // returns 42
let x2 = divide2 5 1 // returns 5
Of course, the point free style is useful, even in F#. For example, when writing a DSL, it is a great way to compose declarative specification (because the primitives express something using higher-level of abstraction). Here, you need to express something that is quite close to normal F# code and, I believe, that is best expressed as normal F# code.