Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types 有没有一种方法可以使用OCaml';s键入系统以强制执行有关值的规则?_Types_Ocaml - Fatal编程技术网

Types 有没有一种方法可以使用OCaml';s键入系统以强制执行有关值的规则?

Types 有没有一种方法可以使用OCaml';s键入系统以强制执行有关值的规则?,types,ocaml,Types,Ocaml,我是OCaml的新手,一直在探索类型系统的功能。我有两个问题 在这种记录类型中,有没有一种方法可以使用OCaml的类型系统来强制执行nums1+nums2=all_nums的规则 type foo={all_nums:int-list;nums1:int-list;nums2:int-list;};; e、 如果nums1=[1]和nums2=[2;3],那么所有的num都必须是[1;2;3] 在该记录类型中,是否有方法使用类型系统强制nums1中的任何项都不应同时位于nums2中,即它们的交

我是OCaml的新手,一直在探索类型系统的功能。我有两个问题

  • 在这种记录类型中,有没有一种方法可以使用OCaml的类型系统来强制执行nums1+nums2=all_nums的规则
    type foo={all_nums:int-list;nums1:int-list;nums2:int-list;};;
    
    e、 如果nums1=[1]和nums2=[2;3],那么所有的num都必须是[1;2;3]

  • 在该记录类型中,是否有方法使用类型系统强制nums1中的任何项都不应同时位于nums2中,即它们的交叉点应为空
  • type bar={nums1:int-list;nums2:int-list;};;
    
    e、 g.如果nums1=[1],nums2也不能包含1


    提前感谢。

    是和否。将调用依赖于运行时值的类型,而OCaml不完全支持依赖类型。传统编程语言通常不支持它们,因为它们使编程变得相当繁琐。例如,从理论上讲,OCaml有足够的依赖类型来支持您的案例,但您不能使用
    list
    int
    ,并且必须对它们使用GADT表示。最终,它几乎无法使用。因为OCaml类型的系统仍然是静态的,所以它必须在程序执行之前检查您的程序是否对所有可能的集合有效。这将极大地限制可类型化程序集

    然而,使用抽象类型和幻影类型相结合,可以对任意不变量进行编码,并依赖类型系统来保存它。诀窍是定义一个小的可信内核,其中不变量是手动执行的

    以你的第一个例子来说

     module Foo : sig 
       type t 
       val create : int list -> int list -> int list -> (t,error) result
     end = struct 
       type t = {all_nums: int list; nums1: int list; nums2: int list;}
       type error = Broken_invariant
       let create all_nums nums1 nums2 = 
          if invariant_satisfied all_nums nums1 nums 2 
          then Ok {all_nums; nums1; nums2}
          else Error Broken_invariant
     end
    
    使用这种密封表示法,不可能在模块
    Foo
    之外创建
    Foo.t
    类型的值,因为满足
    不变量
    的值不是
    真的
    。因此,您的
    Foo
    是受信任的内核—您需要检查是否保留了不变量的唯一地方。其余部分由打字系统负责

    如果使用幻像类型,则可以对更复杂的不变量进行编码,并使其更具表现力,例如

     module Number : sig 
         type 'a t 
         type nat
         type neg
         type any = (nat t, neg t) Either.t
    
    
         val zero : nat t
         val one : nat t
         val of_int : int -> any
         val padd : nat t -> nat t -> nat t 
         val gadd : 'a t -> 'b t -> any
     end = struct 
         type 'a t = int 
         type nat 
         type neg
         type any = (nat t, neg t) Either.t
    
         let zero = 0
         let one = 1
         let of_int x = if x < 0 then Right x else Left x
         let padd x y = x + y (* [see note 2] *)
         let gadd x y = of_int (x + y)
     end
    
    模块编号:sig
    a型t型
    类型nat
    neg型
    键入any=(nat t,neg t)或.t
    val zero:nat t
    瓦尔一号:纳特
    val of_int:int->any
    val padd:nat t->nat t->nat t
    val gadd:'a t->'b t->any
    end=struct
    输入'a t=int
    类型nat
    neg型
    键入any=(nat t,neg t)或.t
    设0=0
    设1=1
    设_int x=如果x<0,则为右x,否则为左x
    让padd x y=x+y(*[见注2]*)
    设gadd x y=of_int(x+y)
    结束
    
    其中
    or.t
    类型定义为
    type('a,'b)t=a的左侧| b的右侧


    笔记 注1。您的第一个示例可以以不可能破坏不变量的方式进行编码,例如,您可以在
    all_nums
    中表示您的类型
    {nums1:int list;nums2:int list}
    并将
    all_nums
    定义为函数,
    让all_nums=list.append

    附注2。事实上,由于OCaml和许多其他编程语言一样,使用模块化算术,两个正数相加可能导致负数,因此我们的示例是拙劣的。但为了举例,让我们忽略这一点:)