他の人が言ったこととは反対に、あなたの問題を正しく理解していれば、ここではクラスを使用しないことをお勧めします。
値は不変であるため、制約を適用する必要があるのは1回だけです。すべてのラッパークラスはオーバーヘッドであり、GCをロードします。代わりに、単純な関数がその役割を果たします。
let inline constrained predicate errormessage value =
if not (predicate value)
then invalidArg "value" errormessage
else value
let positive =
constrained (fun x -> x > 0) "Value must be positive"
let int1 = positive 5 // OK
let int2 = positive -3 // ArgumentException
他のタイプでも同じことができます。
let mustBeLong =
constrained (fun (x:string) -> x.Length > 3) "String must be long"
let str1 = mustBeLong "foobar" // OK
let str2 = mustBeLong "baz" // ArgumentException
構造体内で同じものを使用する:
type Point2D =
struct
val X: int
val Y: int
new(x: int, y: int) = { X = positive x; Y = positive y }
end
let point1 = Point2D(5, 3) // OK
let point2 = Point2D(5, -2) // ArgumentException