Подтвердить что ты не робот

Как провести проверку правильности записей F #

F # упрощает определение типов, таких как

type coords = { X : float; Y : float }

но как определить аргументы ограничения/проверки для конструктора, не вдаваясь в более подробный синтаксис определения класса? Например. если я хочу, чтобы координаты начинались с (0,0) или генерировали исключение.

Кроме того, если я изменю свое определение на класс, мне нужно реализовать Equals() и т.д. весь код плиты котла мне не нужен (и у меня есть на С#, который я пытаюсь уйти).

4b9b3361

Ответ 1

Вы можете сделать реализацию частной. Вы по-прежнему получаете структурное равенство, но теряете прямой доступ к полям и сопоставление шаблонов. Вы можете восстановить эту способность, используя активные шаблоны.

//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

Ответ 2

Существует серия под названием Проектирование с помощью типов на F # для удовольствия и прибыль. В разделе "Принудительное использование конструктора" он рекомендует использовать функции-конструкторы - то, где проверки проверяются до того, как тип создается. Чтобы люди не могли напрямую создавать экземпляры типов, они рекомендуют либо соглашения об именах, либо файлы подписи.

Вы можете найти несколько более подходящих статей и примеров с помощью googling "domain driven design f #".

Обратите внимание, что я иду из С#/не применяя F # к нашему доменному слою (пока;) Я не могу сказать, как один из рекомендуемых методов будет работать в более крупном проекте. Некоторые вещи кажутся... разными в этом смелом новом мире.

Ответ 3

Вы должны использовать синтаксис определения класса:

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