带表达式的F#类型定义

fsl*_*fsl 8 f#

有可能表达这样的事情:

type id = int > 0
Run Code Online (Sandbox Code Playgroud)

我知道它不可能静态地执行,因为这意味着F#具有依赖类型.在C#中,我习惯于使用代码契约来执行此类操作并获得运行时实施.我正在寻找类似的东西.

谢谢

编辑:感谢所有有各种利弊的答案.在那里,我只使用F#的一小部分,这是ocaml核心的一个子集,可以很容易地编程证明.所以没有课程.

byt*_*ter 8

与其他人所说的相反,如果我理解你的问题,我建议不要在这里使用课程.
由于值是不可变的,我们只需要应用约束一次.任何包装类都是开销和加载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
Run Code Online (Sandbox Code Playgroud)

您可以对其他类型执行相同的操作:

let mustBeLong =
    constrained (fun (x:string) -> x.Length > 3) "String must be long"

let str1 = mustBeLong "foobar"  // OK
let str2 = mustBeLong "baz"     // ArgumentException
Run Code Online (Sandbox Code Playgroud)

在结构中使用相同的:

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
Run Code Online (Sandbox Code Playgroud)


Joh*_*mer 1

您可以创建一个通用类,如下所示:

type verify<'t>(t:'t,cond) =
    let mutable tval = t
    let _verify v = if not (cond v) then failwith "bad argument"
    do _verify tval
    member x.get() = tval
    member x.set v =
        _verify v 
        tval <- v
Run Code Online (Sandbox Code Playgroud)

那么你可以使用它

verify(1,fun t -> t>0)
Run Code Online (Sandbox Code Playgroud)

使用.set将重新检查条件。