F# allows to use checked arithmetics by opening Checked
module, which redefines standard operators to be checked operators, for example:
open Checked
let x = 1 + System.Int32.MaxValue // overflow
will result arithmetic overflow exception.
But what if I want to use checked arithmetics in some small scope, like C# allows with keyword checked
:
int x = 1 + int.MaxValue; // ok
int y = checked { 1 + int.MaxValue }; // overflow
How can I control the scope of operators redefinition by opening Checked
module or make it smaller as possible?
You can always define a separate operator, or use shadowing, or use parens to create an inner scope for temporary shadowing:
Finally, see also the
--checked+
compiler option:http://msdn.microsoft.com/en-us/library/dd233171(VS.100).aspx
Here is a complicated (but maybe interesting) alternative. If you're writing something serious then you should probably use one of the Brians suggestions, but just out of curiosity, I was wondering if it was possible to write F# computation expression to do this. You can declare a type that represents
int
which should be used only with checked operations:Then you can define a computation expression builder (this isn't really a monad at all, because the types of operations are completely non-standard):
When you call 'bind' it will automatically wrap the given integer value into an integer that should be used with
checked
operations, so the rest of the code will use checked+
and*
operators declared as members. You end up with something like this:This throws an exception because it overflows on the marked line. If you change the number, it will return an
int
value (because theReturn
member unwraps the numeric value from theChecked
type). This is a bit crazy technique :-) but I thought it may be interesting!(Note
checked
is a keyword reserved for future use, so you may prefer choosing another name)