constructor - problemas - interferencia lógica
Cómo hacer la validación de argumentos de los registros F# (3)
Hay una serie llamada Diseñar con tipos en F # para diversión y beneficio . En la sección "Forzar el uso del constructor", recomienda el uso de las funciones del constructor; allí es donde van las validaciones antes de que se ejemplifique el tipo. Para evitar que las personas ejemplifiquen directamente los tipos, recomienda convenciones de nombres o archivos de firmas.
Puede encontrar varios artículos y ejemplos más relevantes buscando en Google "diseño controlado por dominio f #".
Tenga en cuenta que vengo de C # / no he aplicado F # a nuestra capa de dominio (aún;) realmente no puedo decir cómo alguno de los métodos recomendados funcionaría en un proyecto más grande. Algunas cosas seguramente parecen ... diferentes en este valiente nuevo mundo.
F # hace que sea fácil definir tipos como
type coords = { X : float; Y : float }
pero, ¿cómo defino los argumentos de restricciones / verificación para el constructor sin entrar en la sintaxis de definición de clase más detallada? Por ejemplo, si quiero que los acordes comiencen desde (0,0) o lancen una excepción.
Además, si cambio mi definición a una clase, necesito implementar Equals (), etc., todo el código de la placa de la caldera que no quiero (y que tengo en C # del que estoy tratando de alejarme).
Puedes hacer la implementación privada. Aún obtienes igualdad estructural pero pierdes el acceso directo al campo y la coincidencia de patrones. Puedes restaurar esa habilidad usando patrones activos.
//file1.fs
type Coords =
private {
X: float
Y: float
}
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Coords =
///The ONLY way to create Coords
let create x y =
check x
check y
{X=x; Y=y}
let (|Coords|) {X=x; Y=y} = (x, y)
//file2.fs
open Coords
let coords = create 1.0 1.0
let (Coords(x, y)) = coords
printfn "%f, %f" x y
Tienes que usar la sintaxis de definición de clase:
type coords(x: float, y: float) =
do
if x < 0.0 then
invalidArg "x" "Cannot be negative"
if y < 0.0 then
invalidArg "y" "Cannot be negative"
member this.X =
x
member this.Y =
y