Search code examples
.netexceptionf#naninfinity

System.ArithmeticException not thrown in F#


Consider the following code

let a = 5. / 0.
let b = sin a
let c = sqrt(-5.)

It produces both Infinity and NaN. In both cases I want to have an exception thrown (for debuging purposes).

I use Visual Studio 2010. I set up Debug/Exceptions.../Common Language Runtime Exceptions/System/System.ArithmeticException to "Thrown", but when running the code, no exception is thrown.

Any idea why and how to throw an exception on NaN or Infinity?


Solution

  • As others noted, you'll have to check for the NaN condition explicitly. If you wanted to do this using some advanced F# features, then you could also use computation expressions.

    It is possible to define a builder that automatically checks for Nan when you bind value using let!. Then you could write something like:

    check { let! a = 5. / 0.    // 'a' is checked here
            let! b = sin a      // 'b' is checked here
            let c = sqrt(-5.)   // 'c' is not checked (no 'let!')
            return a, b, c }
    

    This may be too complicated mechanism for just simple checks, but I find it quite nice. The definition of the computation builder looks like this (you'll need to add While, For and some others to support all language constructs):

    open System
    
    type CheckedBuilder() = 
      member x.Bind(v:float, f) = 
        if Double.IsNaN(v) |> not then f v
        else raise (new ArithmeticException())
      member x.Return(v) = v
    
    let check = CheckedBuilder()