myślę najlepiej jest statyczny element:
type Bounds = { Min: float; Max: float }
with
static member Create(min: float, max:float) =
if min >= max then
invalidArg "min" "min must be less than max"
{Min=min; Max=max}
i używać go jak
> Bounds.Create(3.1, 2.1);;
System.ArgumentException: min must be less than max
Parameter name: min
at FSI_0003.Bounds.Create(Double min, Double max) in C:\Users\Stephen\Documents\Visual Studio 2010\Projects\FsOverflow\FsOverflow\Script2.fsx:line 5
at <StartupCode$FSI_0005>[email protected]()
Stopped due to error
> Bounds.Create(1.1, 2.1);;
val it : Bounds = {Min = 1.1;
Max = 2.1;}
Jednakże, jak podkreślić, wielki dół stroną tego podejścia jest, że nic nie stoi na przeszkodzie, aby bezpośrednio stworzyć "nieważny" rekord. Jeśli jest to poważny problem, należy rozważyć użycie typu klasy dla zagwarantowania swoich niezmienników:
type Bounds(min:float, max:float) =
do
if min >= max then
invalidArg "min" "min must be less than max"
with
member __.Min = min
member __.Max = max
razem z aktywnym wzorzec dla wygody podobny do tego, co można uzyskać z dokumentacji (w szczególności w odniesieniu do dopasowywania wzorca):
let (|Bounds|) (x:Bounds) =
(x.Min, x.Max)
wszystko razem:
> let bounds = Bounds(2.3, 1.3);;
System.ArgumentException: min must be less than max
Parameter name: min
at FSI_0002.Bounds..ctor(Double min, Double max) in C:\Users\Stephen\Documents\Visual Studio 2010\Projects\FsOverflow\FsOverflow\Script2.fsx:line 4
at <StartupCode$FSI_0003>[email protected]()
Stopped due to error
> let bounds = Bounds(1.3, 2.3);;
val bounds : Bounds
> let isMatch = match bounds with Bounds(1.3, 2.3) -> "yes!" | _ -> "no";;
val isMatch : string = "yes!"
> let isMatch = match bounds with Bounds(0.3, 2.3) -> "yes!" | _ -> "no";;
val isMatch : string = "no"
O ile się nie mylę, płyty nie daje jednoznacznej konstruktora. – Mathias
Nie, potrzebujesz systemu typu silniejszego, takiego jak typy udoskonalania w [F *] (http://rise4fun.com/FStar). Kontrakt Code może wymusić ten niezmiennik w C#, ale AFAIK, sprawdzanie kontraktu Code Contracts, nadal nie działa poprawnie dla projektów F #. –
Możesz rozważyć przestawienie się na struktury, które również zapewniają strukturalną równość. Dopasowywanie wzorców można ułatwić poprzez aktywne wzorce. Zaletą jest to, że można łatwo wymusić warianty [za pomocą jawnych konstruktorów, a następnie konstruować, itp.] (Http://stackoverflow.com/questions/12600574/argument-validation-in-f-struct-constructor). – pad