Types 结构能否在标准ML中实现多个签名?

Types 结构能否在标准ML中实现多个签名?,types,sml,Types,Sml,我最近想知道标准的ML结构是否可以实现多个签名,类似于Java中一个类如何实现多个接口。通过快速搜索发现,Bob Harper说这确实是可能的(我的重点): […]ML中签名和结构之间的关系是 多对多,而在某些语言(如Modula-2)中 关系是一对一或多对一。这意味着在ML a中 签名可以作为许多不同结构的接口, 结构可以实现许多不同的签名 然而,我找不到语法,粗略地看一下修改后的定义中的模块语法似乎不支持上面的引用 我的问题是: 可能吗 如果是,语法是什么 编辑:在玩了一些游戏之后,我认为B

我最近想知道标准的ML结构是否可以实现多个签名,类似于Java中一个类如何实现多个接口。通过快速搜索发现,Bob Harper说这确实是可能的(我的重点):

[…]ML中签名和结构之间的关系是 多对多,而在某些语言(如Modula-2)中 关系是一对一或多对一。这意味着在ML a中 签名可以作为许多不同结构的接口, 结构可以实现许多不同的签名

然而,我找不到语法,粗略地看一下修改后的定义中的模块语法似乎不支持上面的引用

我的问题是:

  • 可能吗
  • 如果是,语法是什么
  • 编辑:在玩了一些游戏之后,我认为Bob Harper实际上指的是签名匹配。此代码段是一个小示例,其中一个结构与两个不同的签名匹配:

    signature S1 = sig val s1 : int end
    signature S2 = sig val s2 : string end
    
    functor F1 (A : S1) = struct val f1 = A.s1 end
    functor F2 (B : S2) = struct val f2 = B.s2 end
    
    structure C =
    struct
      val s1 = 1
      val s2 = "1"
    end
    
    structure F1C = F1 (C)
    structure F2C = F2 (C)
    
    在这一点上,我假设,是的,一个结构可以被视为实现了多个签名,但在结构声明中使用签名规范无法强制实现,例如:

    structure C : S1 and S2 = ...
    

    没有语法可以用单个注释强制执行它,但您可以这样做

    structure C = struct ... end
    structure C1 : S1 = C
    structure C2 : S2 = C
    
    如果您只想进行健全性检查,但避免使用辅助结构名称污染作用域,则可以将其设置为本地:

    structure C = struct ... end
    local
      structure C1 : S1 = C
      structure C2 : S2 = C
    in end
    
    不幸的是,不能在结构绑定中使用通配符

    您建议的表示法会很棘手,因为它会有效地在签名上引入交集运算符。这将产生深远的影响。例如,考虑:

    signature S1 = sig type 'a t; val v : int t; val w : string t end
    signature S2 = sig val v : int end
    functor F (X : S1 and S2) = (* what is X.t here? *)
    
    对于
    X.t
    的类型,有两种可能的解决方案,以便
    X.v
    的类型与两个签名一致:或者

    type 'a t = int
    


    问题是它们是无与伦比的,也就是说,没有一个比另一个更好。在一种情况下,
    X.w
    将是一个int,在另一种情况下是一个字符串。本质上,这里发生的是通过后门引入一种高阶统一形式,这在一般情况下是不可判定的。

    谢谢。似乎结构的类型唯一重要的地方,函子的参数,我们不能将同一个结构用作两个不同的签名。除非,我们应用你的技巧
    F(结构C1=C;结构C2=C)
    。我还意识到有一种方法可以组合两个签名,使用
    include
    signatures12=sig include S1 include S2 end
    。但是,是的,它无法用您给出的交叉点类型示例进行编译。@IonuțG.Stan,这不太正确。当然,您可以手动写出所需的组合签名(如果存在),它将是S1和S2的子类型(因为签名是结构类型)。你不能把它表示为交叉点。另外,我不确定我是否理解你想要实现的目标。你为什么要写这样一个函子?这是一个纯粹出于好奇的问题,我并不是真的想用它来做什么。另外,关于
    包括
    。我意识到我可以手动合并两个签名,但是使用
    include
    可以“合并”两个签名,而不实际声明一个。类似于:
    结构C:sig include S1 include S2 end=…
    。对于
    结构C:S1和S2=…
    ,这看起来像是一个更详细的符号,但它没有交集类型的语义。
    type 'a t = 'a