Aquí hay una alternativa complicada (pero tal vez interesante). Si estás escribiendo algo serio, entonces probablemente deberías usar una de las sugerencias de Brians, pero solo por curiosidad, me preguntaba si era posible escribir la expresión de cálculo F # para hacer esto. Se puede declarar un tipo que representa int
que debe ser utilizado únicamente con operaciones controladas:
type CheckedInt = Ch of int with
static member (+) (Ch a, Ch b) = Checked.(+) a b
static member (*) (Ch a, Ch b) = Checked.(*) a b
static member (+) (Ch a, b) = Checked.(+) a b
static member (*) (Ch a, b) = Checked.(*) a b
A continuación, se puede definir un generador de expresiones de cálculo (esto no es realmente una mónada en absoluto, porque los tipos de operaciones son completamente no estándar):
type CheckedBuilder() =
member x.Bind(v, f) = f (Ch v)
member x.Return(Ch v) = v
let checked = new CheckedBuilder()
Cuando se llama 'bind' que se ajustará automáticamente el valor entero dado en un entero que se debe utilizar con checked
operaciones, por lo que el resto del código utilizará comprobado +
y *
operadores declarados como miembros. Usted termina con algo como esto:
checked { let! a = 10000
let! b = a * 10000
let! c = b * 21
let! d = c + 47483648 // !
return d }
Esto arroja una excepción porque se desborda en la línea marcada. Si cambia el número, devolverá un valor int
(porque el miembro Return
desenvuelve el valor numérico del tipo Checked
). Esta es una técnica un poco loca :-) ¡pero pensé que podría ser interesante!
(Nota checked
es una palabra clave reservada para uso futuro, por lo que prefieren elegir otro nombre)
Por el contrario, es posible invocar "marcada" en todas las declaraciones en un proyecto de C#? –
@Heath Hunnicutt: lo contrario se puede lograr con las opciones del compilador, ya sea en el IDE o en la línea de comandos. –