SML’97的SML模块系统发生了重大变化。 此更改的动机是简化 模块化系统,主要是通过削弱结构共享的概念, 并通过添加定义来提高签名的表达能力 类型规范。 增加了定义型规范 对类型共享规范的新限制。 在许多情况下 共享规范本应在SML’90中使用,而在SML'97中则是 使用定义类型是必要的,或者可能只是更好的风格 规范。 在SML'97中,结构没有唯一的、可检查的静态 身份和结构共享被视为缩写 用于隐式类型共享。缺少结构级等效的 很快发现定义型规格很难,SML/NJ 实现了这个有用的功能( 第1.6.2节 ).
1.3.1. 在签名中键入缩写
SML’97定义,第G.1节。
人们早就意识到SML的原始签名语言 出于某些目的,90年代的表现力不够。 特别是,它 通常不可能同时表明存在和 规范中类型组件的定义。 在特殊情况下, 可以使用 定义的 类型共享规范,如 签名S= 信号发生器 类型t共享类型t=int 结束 但如果
t吨 的定义是一种类型 表情似的
int列表 所以在97年的SML中 类型规范的定义扩展为允许 表格规格: 类型 tyvarseq泰康 = 第y天 我们将这种规范称为 定义规范 (同时 有时称为 类型缩写规范 ). 使用此 按照某种规范,我们可以更整洁地重写上述签名 如下: 签名S= 信号发生器 类型t=int列表 结束 允许在签名中使用类型定义规范,可以 编写一个更全面地捕获或约束类型的签名 结构中的信息。 它还使其更实用 下面描述的签名匹配的不透明形式 (第节 1.3.9 ), 因为可以更好地控制哪些导出类型是抽象的 ( 不透明的 )那些是混凝土的( 透明的 ).
SML/NJ从版本开始引入了类型定义规范 0.93,它们也在Caml Special Light和 奥卡姆(?)。 SML’97的主要改进是减少 混淆类型定义规范和类型共享之间的交互 specs通过对类型共享specs施加新的限制。 我们限制 可以在共享规范中显示的类型与在中指定的类型 当前签名(第节 1.3.4 ), 我们禁止定义共享规范(第节 1.3.5 ). 我们还增加了 使用“
其中类型 “语法到 将定义附加到先前定义的签名(第节 1.3.3 ). 最终的设计为我们提供了更多 表达能力超过SML’90。
引入类型定义规范的动机也适用于 结构规范。 在SML’90程序中,我们经常使用定义 结构 共享规范,这种形式的共享规范是 SML'97是不允许的。 显然是类型定义的结构模拟 规格将是一个方便的替代品,但不幸的是SML'97没有 提供它们。 因此,SML/NJ填补了这一空白,如下所述 关于结构定义规范的章节 ( 第1.6.2节 ).
1.3.2. 数据类型复制规范
中描述了数据类型复制声明 第1.1.5节 .一个 提供了类似的数据类型复制规范表 对于签名,它具有与声明相同的语法: 数据类型 典型值 = 数据类型 长子 数据类型复制规范与数据类型规范的作用相同 正如定义类型规范对简单类型规范所做的那样,我们使用 学期 定义规范 涵盖这两种形式。 下面是一个示例 结构A= 结构 数据类型'a t=C|D of'a*'a t 结束 签名S= 信号发生器 数据类型t=数据类型A.t 结束 请注意,尽管
A.t公司 (因此
t吨 )是 一元类型构造函数,我们不包括形式类型变量 数据类型复制规范中的参数。此规范的效果 是定义类型组件
t吨 与…相同
A.t公司 此外,它还隐式指定 数据构造函数
C类 和
D类 与关联
A.t公司 。因此,在functor声明中,例如 函子F(X:S):sig val F:'a X.t->'a a.t end= 结构 乐趣f(X.C)=X.C |f(X.D(X,y))=公元 结束 我们保证
X吨 和
A.t公司 是 相同类型和
公元 和
X、D 是一样的 数据构造函数。
如下所述 第1.3.6节 , 数据类型复制规范的主要用途之一 是替代定义共享约束,即 不再允许。
1.3.3. 使用修改签名
其中类型
有时,当我们需要时,使用定义类型规范“为时已晚” 一个。 通过这一点,我指的是我们想要的类型 define在已声明的签名中指定, 也许在图书馆。 例如,假设
S1(第一阶段) 是一个大的 具有简单类型规范的签名
t吨 : 签名S1= 信号发生器 t型 …(*二十种其他规格*) 结束 稍后我们要使用
S1(第一阶段) ,但我们希望在中指定 另外
t吨 是
int列表 ).
一个可以插入
S1(第一阶段) 的定义签名表达式代替
S1(第一阶段) ,修改为适当的定义
t吨 ,但当
S1(第一阶段) 是一个很大的签名。 SML’97以
其中类型 定义。 它可以修改 通过添加其类型之一的定义来创建现有签名。 在我们的示例中,我们将按如下方式使用它: 签名S2= 信号发生器 结构A:S1,其中类型t=int列表 结束 给你
其中类型 定义修改或增加了 签名
S1(第一阶段) 、和
S1,其中类型A.t=int 是一种新的签名表达式。 使用
其中类型 我们能够表达以前无法表达的东西 定义共享约束,如 签名S2= 信号发生器 结构A:S1,其中类型t=int列表 结束 我们甚至可以使用
其中类型 条款,如果 要定义的类型埋在子结构内,如 以下示例 签名U= 信号发生器 结构A:S1 ... 结束 签名S2= 信号发生器 结构B:U,其中类型A.t=int list 结束 请注意,这里是
其中类型 条款 是符号路径
A.t公司 (a) 长子 在中 定义的术语),其效果是增加 规范
t吨 在里面
S1(第一阶段) .
由where子句定义的数据类型。 由
其中类型 子句可以是一个 指定为数据类型的。 结构A= 结构 数据类型'a t=C|D of'a*'a t 结束 签名S= 信号发生器 数据类型'a t=C|D of'a*'a t 结束 签名U=S,其中类型“a t=”a a.t 在本例中
其中类型 相当于嵌入式 数据类型复制规范,so签名
U型 能够 等效定义为 签名U= 信号发生器 数据类型t=数据类型A.t 结束 从技术上讲,该定义对 受影响的主要规范及其在where中的定义 条款。 例如,以下签名声明是合法的, 签名S= 信号发生器 数据类型t=t 结束 其中类型t=int 虽然这样的签名无法实现,因为 基本规范
t吨 及其在中的定义 where子句不一致。 编译器可能会 检查这些明显的不一致(但SML/NJ没有)。
where定义右侧的上下文。 右侧的类型表达式
哪里 类型 定义不能提及指定的类型 它在签名中修改。 下面的例子是 非法(假定没有类型
t吨 定义在 本声明的上下文)。 签名S= 信号发生器 类型s t型 结束 其中类型s=t 这种限制的原因是我们想避免示例 如下所示 签名S= 信号发生器 类型s 结构A: 信号发生器 t型 值x:s*t 结束 结束 签名U=S,其中类型S=A.t*A.t 如果
A.t公司 位于的右侧
哪里 类型 子句引用签名中指定的类型
S公司 ,那么我们将创建一种不受欢迎的循环 依赖项,其中类型
秒 取决于底座
A类 因为where定义,而
A类 取决于
秒 因为
秒 在中提到
A类 的签名。
我们希望能够使用替换任何签名定义 这个
其中类型 用等价定义构造 将where定义替换为 类型缩写规范和数据类型复制规范。 很明显 签名
U型 在最后一个示例中不能是 在没有
其中类型 本解释中的条款 该子句右侧的上下文。 这就是为什么我们 从上下文中排除已修改签名的正文 右侧,从而使此示例非法。
SML/NJ差异 :自然思维方式 这个
其中类型 构建是一种 引入类型缩写规范(或数据类型复制规范) 转换为先前定义的签名,从而生成扩展的 签名的版本。 原则上应该可以 用放置的定义等效地定义该增强签名 直接在受影响类型的规范点。 这个 事实上,SML/NJ是如何实现的
其中类型 定义。 因此 签名S= 信号发生器 t型 结束 其中类型t=int 由编译器转换为声明 签名S= 信号发生器 类型t=int 结束 因此,将类型缩写规范视为主要结构 定义
其中类型 就这一点而言。
然而,由于技术原因,定义做的事情是向后的, 治疗
其中类型 作为一个基本概念和 定义类型缩写规范(但不是数据类型复制 规范)
其中类型 和
包括 . 因此,在定义中, 签名S= 信号发生器 类型t=int 结束 被翻译成 签名S= 信号发生器 包括sig类型t end,其中类型t=int 结束 在大多数情况下,这种方法上的差异并不重要。 定义的版本允许更多签名合法,但我们 辩称它们不是优秀程序员会有的签名 想要写作。 下面是一个合法签名的示例 SML/NJ不接受(由于Marin Elsman的原因,请参阅SML/NJ错误1330): 签名S= 信号发生器 类型s 结构U:sig 键入'at 类型u=(int*real)t end where类型'a t=s 结束,其中类型U.U=int 我们把它留给勤奋的语言律师去验证 根据定义,这是可以接受的,但这是非常清楚的 这不是我们想鼓励程序员编写的那种东西。 确定此签名是否有意义是 建立高阶变量的方程组 (
秒 ,
u个 、和
t吨 )然后 寻求该系统的解决方案。 我们希望 签名定义的敏感性应该更加明显。
此签名声明不被接受的一个特殊原因 SML/NJ认为SML/NJ不允许
其中类型 要应用于已具有 定义规范。 签名的一个简单示例 因此被拒绝的是: 签名S= 信号发生器 类型s 类型t=s 结束 其中类型t=int 写这篇文章更明智的方法是 签名S= 信号发生器 类型s 类型t=s 结束 其中类型s=int 哪一个 是 SML/NJ可接受。
1.3.4. 共享到本地路径的限制
在SML’90中,共享规范是一个独立的规范 在签名中,但在SML'97中,共享规范修改了 它们在文本中遵循的规范(顺序规范) 签名。 共享约束中提到的组件必须 所有这些都来自共享约束修改的规范。 因此,在 [1] 签名S= [2] 信号发生器 [3] 类型s [4] 结构A:sig [5] 类型t [6] u型 [7] 共享类型t=u [8] 共享类型t=s [9] 结束 [10] 结束 第[7]行中的共享约束适用于 行[5]和[6],并且是合法的,因为类型名称
t吨 和
u个 共享约束中提到的 这些规格。 另一方面,第[8]行的共享约束, 不合法,因为其“范围”由行组成[5-7],而 提到类型
秒 绑定lin行[3]。 同样的规则 适用于结构共享约束。
共享约束的这种范围限制是主要原因 为什么共享约束可能需要转换为定义约束 规范或
哪里 定义。 声明
S公司 以上内容可以改写为以下97年的合法SML 宣言。 [1] 签名S= [2] 信号发生器 [3] 类型s [4] 结构A:sig [5] 类型t=s [6] 类型u=t [7] 结束 [8] 结束 它也可以合法重写(根据定义)为 [1] 签名S= [2] 信号发生器 [3] 类型s [4] 结构A:sig [5] 类型t=s [6] u型 [7] 共享类型t=u [8] 结束 [9] 结束 但这个版本提出了一个微妙而有争议的观点。 通知 类型
t吨 在其规范中定义为 第[5]行,并且在 第[7]行。
1.3.5. 共享和定义规范不受干扰
在SML’90中,有两种类型共享,一种是 所涉及的类型是“正式的”或未知的,我们称之为 一致性 共享 和另一种类型,其中一种类型未知,另一种未知 已知,我们称之为 定义共享 。这是一个典型的 相干共享示例: 签名S= 信号发生器 t型 类型s 共享类型t=s 结束 在这种情况下,两者都不是
t吨 也不是
秒 确定, 但共享规范要求在实例化它们时 都实例化为同一类型。
定义共享的一个简单示例是: 签名S= 信号发生器 t型 共享类型t=int 结束 其中类型
t吨 有效定义为等于
整数 共享约束。
在SML'97中,可以在其 原始规范,或事后使用“where-type”语法,所以 定义共享似乎是多余的。 此外,相互作用 在定义共享和直接定义之间可以创建 谜题,例如: 签名S= 信号发生器 类型s 类型t=s列表 键入'a'u 类型v=int u 共享类型t=v 结束 这里,类型
t吨 和
v(v) 直接在中定义 形式类型的术语
秒 和
u个 ,然后 共享规范将它们等同起来。 如果我们想的话 确定此签名是否可满足,我们必须查看 是否存在满足方程的类型s和u s列表=int u 求解这样的二阶方程通常是一个棘手的问题, 也许无法解决。 为了解决这个问题,SML’97设计 通过禁止定义共享来排除此类示例 单词,共享规范中涉及的类型需要 要正式或“灵活”。
从技术上讲,定义要求涉及类型构造函数 在共享约束中,应(1)未定义为类型函数,以及(2) 未根据某些“刚性”类型构造函数(即类型 先前在上下文中定义的构造函数)。
我们选择将“可共享”定义为: 不 应用于类型构造函数的定义。 我们将使用该术语 “defined”与sharable相反。 更微妙的定义是 可能; 参见注释 “共享类型” 如下所示。
因此,以下签名是非法的 签名S= 信号发生器 类型s=int(定义了*s) 类型t(*t可共享*) 共享类型t=s(*s不可共享*) 结束 并且必须重新表述为(例如): 签名S= 信号发生器 类型s=int 类型t=s 结束 使用“where-type”定义,事情会稍微复杂一些。 安 内部类型共享约束可能受外部定义的影响 约束,如下例所示: 签名S1= 信号发生器 类型s t型 共享类型t=s(*好,因为s和t在这里是可共享的*) 结束 其中类型t=int; (*这将s和t转换为刚性类型*) 这是合法的,但以下声明不是: 签名S2= 信号发生器 结构A:S1 v型 共享类型v=A.s(*A.s不灵活*) 结束; 然而,S2可以很容易地转换为下面的合法S3 用定义替换外部共享约束。 签名S3= 信号 结构A:S1 类型v=A.s 结束; 通常,我们建议避免共享可以轻松实现的约束 用定义规范表示。 所以你应该总是喜欢 类型t=s 到 t型 共享类型t=s。 这同样适用于结构共享和结构定义规范 (它们是SML/NJ语言的扩展)。 违反这一新规定 强制约束通常可以通过替换结构来消除 通过结构定义规范共享,例如替换 结构A:SIGA 共享A=B.C 具有 结构A:SIGA=不列颠哥伦比亚。
1.3.5.1具有相同签名的结构共享的SML/NJ例外
SML/NJ为共享刚性规则提供了一个重要例外 类型。 这种情况下,类型共享由结构隐含 在具有相同签名的两个结构之间共享。
下面是一个示例 签名S= 信号发生器 类型t=int 结束 签名S1= 信号发生器 结构A:S 结构B:S 共享A=B 结束 这在SML/NJ中是允许的,因为A和B具有相同的签名,甚至 尽管共享约束等价于 共享类型A.t=B.t A.t和B.t有严格的规范 类型t=int。
1.3.5.2哪些类型是可共享的(主要针对语言律师)
关于构造函数应该是什么类型存在一些争议 允许共享约束。 我们可以通过 以下示例 签名S= 信号发生器 类型s 类型t=s u型 共享类型t=u 结束 根据我们的上述定义,
t吨 已定义,因此不可共享,以及 此签名声明被拒绝。 然而,从技术上讲 的语义表示
t吨 签名中是类型函数
\(). (() 纳秒 ) (nullary型函数,其中
纳秒 是语义类型 的“名称”
秒 ),并且此类型函数是eta-等价的 到
纳秒 ,一个简单的灵活类型名称。 因此, 如果这个eta还原是 假设,
t吨 符合定义的要求,可以出现在 共享约束。 另一方面,考虑 签名S= 信号发生器 类型s 类型t=s列表 u型 共享类型t=u 结束 以下是
t吨 是类型函数
\(). (()ns)列表 , 它不会简化为简单的类型名,因此共享约束 显然是非法的。 我们采用更简单、更具限制性的 可分享的是,它更容易解释,而且它接纳了所有合理的因素 用法。 我们声称,它在 签名书写。 它还可以更简单、更高效地 实施(至少对于SML/NJ)。 以下是根据 更复杂的定义版本(感谢 DIKU): 签名S1= 信号发生器 t型 类型s=t end,其中类型s=int 签名S2= 信号发生器 t型 类型s=t 共享类型t=s 结束 签名S3= 信号发生器 类型s 结构U: 信号发生器 键入'at 类型u=(int*real)t end where类型'a t=s 结束,其中类型U.U=int 尚不清楚这样的例子对任何人都有任何重要性 除了语言律师。 最后一个特别反常:阅读 签名不应该是解谜的练习!
1.3.6. 用定义规范替换“定义”共享
我们过去可以使用定义共享 规范,如图所示: 签名S2= 信号发生器 结构A:S1 共享类型A.t=int 结束 但这种分享并不合法,因为
整数 不是 主体的局部路径
S2系列 . 在某些情况下,您可以选择使用共享 规范或类型定义规范或
其中类型 条款。 例如,以下三项签名声明
S公司 等效: 签名T=签名类型结束 签名S= 信号发生器 t型 结构A:T 共享类型t=A.s 结束 签名S= 信号发生器 t型 结构A:sig类型s=t端(*扩展t*) 结束 签名S= 信号发生器 t型 结构A:T,其中类型s=T 结束 最后一个示例可能表明,可以随时替换 类型共享规范与类型定义规范或
哪里 类型 子句,但情况并非如此,如图所示 通过以下示例: 签名S= 信号发生器 类型s 结构A:sig 数据类型d=第d个,共s个 数据类型t=K 结束 共享类型s=A.t 结束 无法重新排列签名的定义
S公司 以便共享规范可以替换为 定义。 然而,这个例子有点做作 尚不清楚是否会产生任何严重的实际影响 如果我们放弃写这种签名的能力 使用定义规范代替共享。
这个
其中类型 construct还可用于定义 类型在基签名中指定为数据类型,这使得 它与下面描述的数据类型复制规范有关。 这里有一个例子。 结构A= 结构 数据类型t=t 结束 签名S= 信号发生器 数据类型t=t 结束 签名S1=S,其中类型t=A.t 这种能力可以 定义 中需要数据类型规范 以取代定义共享约束,如 以下示例: 签名S= 信号发生器 数据类型t=t 共享类型t=A.t 结束 本例中的定义不需要检查 规范的数据类型“签名”及其在
其中类型 子句必须一致,但编译器 可以执行某种级别的检查。 至少可以检查一下 定义右侧的类型也是 数据类型,除此之外,它可能会检查数字和 数据构造函数的名称一致。
1.3.7. 结构共享作为类型共享的派生形式
在SML’97中,结构共享从一流变弱 派生语法特征,即解释的特征 在转换为类型共享语法方面。 这是真的 模块系统的表现力减弱。 在SML’90中, 其中每个结构都具有唯一的静态身份和结构 可以静态检查共享,可以使用结构共享 不仅要保证两个结构中的类型一致,而且要保证 构成这些类型关联接口的值还包括 共享。 例如,如果两个结构
A类 和
B类 有签名
作战需求文件 定义如下 签名ORD= 信号发生器 t型 值比较:t*t->t 结束 共享规范 共享A=B 不仅保证了类型
A.t公司 和
B.t公司 是相同的,但比较操作
A.comp公司 和
B.comp公司 都是一样的,即
A类 和
B类 在 同一类型。
在SML'97中,我们仍然可以编写这样的共享规范,但它们 被视为所有可能的隐含类型共享的缩写 规范。 在这种情况下,上述结构共享规范转换为 以下类型共享规范: 共享类型A.t=B.t 这并不意味着比较运算符A.comp和B.comp 同意,因此它严格弱于SML中的结构共享规范 '90.
可以恢复旧的结构共享功能 当所讨论的结构包含(生成)类型时 用于唯一标识结构。 实际上,使用了类型 作为一个独特的标签来保证整个结构的身份。 如果没有“作弊”,也就是说,如果没有其他独立的作弊者,这种做法是可行的 定义的结构包含相同的标记类型。
关于结构共享的弱版本需要注意的另一件事 它是不可传递的。 例如 共享A=B和B=C 并不一定意味着 共享A=C 感到满意。 下面是一个示例 签名S0= 信号发生器 t型 结束 签名S= 信号发生器 结构A:S0 结构B:信号端 结构C:S0 共享A=B和B=C 结束 自结构
B类 没有类型组件,共享 方程
A=B 和
B=C 是空虚的,并且 转化为完全没有类型共享。 特别是,他们不保证 那个
A.t=C.t ,因此并不意味着共享 约束
A=C .
出现的路径是结构共享规范,也必须满足 中描述的位置限制 章节 1.3.4 。也就是说,指定共享的结构必须 都是具有相同签名的组件(或子组件) 包含共享规范。这将确保类型共享 结构共享转换为的规范将满足 类型共享的局部性约束。
这种地方性规则通常会排除“定义结构” 共享规范”,这在SML'90中使用得相当频繁。 怎么 我们应该重写这样的定义结构共享规范吗? 一个 方法是将结构共享扩展到相应的集合 类型共享规范,然后替换定义的类型共享 规范中包含适当的“where-type”定义。 例如, 给定结构a,定义如下: 结构A= 结构 数据类型t=t 结束 SML’90签名 签名S= 信号发生器 结构B:sig型t端 共享B=A 结束 可以重写为 签名S= 信号发生器 结构B:sig类型t端,其中类型t=A.t 结束 当然,如果a中涉及十几种类型,而不仅仅是 第一,这可能导致代码不愉快的扩展。 为了这个 原因是,最好有一个结构类似物 定义规范,以便我们可以编写如下内容: 签名S= 信号发生器 结构B:sig类型t端=A 结束 事实上,SML/NJ支持这种定义结构规范; 看见 第1.6.2节 .
1.3.8.
包括 六倍x射线光电子能谱
的语法
包括 规范已推广 以允许任意签名表达式以及签名名称。 此扩展的目的是允许定义类型规范 定义为
包括 和
哪里 类型 作为派生形式。因此 类型t= 第y天 应该是的缩写 包括sig类型t结束,其中类型t= 第y天 这似乎有点复杂,因为简单类型定义规范 就其本身而言,似乎是一个更基本的概念,但这 之所以选择这种方法,是因为 定义。 简单处理存在技术问题 定义规范作为基本构造和定义
哪里 类型 通过句法翻译为定义规范,以及 这就是自由变量捕获的问题。 例如,在 遵循签名定义
u个 出现 在中
其中类型 子句与类型不同
u个 在正文中指定
S公司 . 签名S= 信号发生器 u型 t型 结束 其中类型t=u*u 如果我们要消除
其中类型 中的子句 通过文本将定义向内移动到
t吨 是指定的,我们会 签名S= 信号发生器 u型 类型t=u*u 结束 这显然是不正确的,因为
u个 在定义中
t吨 已被当地人捕获 装订
u个 因此,尽管这种消除
其中类型 可以在语义结构层面工作, 它不作为文本转换工作(即作为派生形式)。
1.3.9. 不透明签名匹配
:>
以前版本的SML/NJ支持特殊结构声明 形式 抽象S:SIG=结构。。。 结束 其目的是创建签名的“抽象”实例
信号 。SML'90中没有此功能 原因,但它的需要是真实的。
在SML'97中,提供了类似的功能 使用特殊签名约束的“不透明”签名匹配 语法
S:>信号 。例如,以下声明 与上面给出的旧“抽象”声明具有相同的效果。 结构S:>SIG=结构。。。 结束 不透明签名匹配的效果是正式的或灵活的 签名SIG中的类型获得新的抽象实例化,这些实例化是 与结构表达式中的相应类型不同 受到约束。 下面是一个更详细的示例: 签名SIG= 信号发生器 类型s 类型t=int val零:s val成功:s->s 值f:s->t 结束 结构运输:SIG= 结构 类型s=int 类型t=int 值0=0 乐趣成功x=x+1 乐趣f x=x 结束 结构不透明:>SIG= 结构 类型s=int 类型t=int 值0=0 乐趣成功x=x+1 乐趣f x=x 结束 由于正常的透明签名匹配,Transp.s是 相当于
整数 ,运输也是如此。但在
不透明 ,
不透明。 t吨 仍然相当于
整数 ,因为签名中的定义,但
不透明。 秒 是不同于
整数 .
在两个地方使用不透明签名可能有意义 匹配。 在上述正常结构声明中的第一个 示例,然后指定函子的结果签名。 函数F(X:PSIG):>SIG=结构。。。 结束 当函子定义为具有如下不透明结果签名时, 每次应用函子时 结果签名已创建。
使用不透明的签名匹配形式是没有意义的 函子的形式参数(即在输入端作为 与输出端相反)。
1.3.10. 相等类型规范,推断相等属性
1.3.11. 打开 和 地方的 规范表格已删除
SML’90的定义有两种特殊形式的规范 可用于签名:
本地。。。 在..端 和
打开 这些表格,特别是当地规范,包括 由于定义中的技术原因引入。 这些规范表格都已在SML'97中删除。 这些 SML’90的功能存在争议,因为当完全使用时 一般来说,他们的行为没有明确的直觉依据, 尽管它们具有精确的技术含义和技术作用 在定义的语义中。 除了一个特殊功能外,这些功能的实用性也值得怀疑 限制案例,开放和本地相结合,允许 规范中类型路径的缩写。 例如: 结构A= 结构 类型t=int 结束; 签名S= 信号发生器 本地打开A in 值x:t 结束 结束; 给你
打开A 规范允许
A.t公司 缩写为
t吨 ,而
地方的 形式阻止组件
A类 从被添加到
S公司 按照规范。 所以这个签名的定义
S公司 等于 写作 签名S= 信号发生器 值x:A.t 结束;
在SML/NJ,根据 SML’90定义,但部分实现了 只支持上面的路径缩写习惯用法。 事实上,公开 表单的实现使其可以用于缩写 即使没有周围的本地规范也会产生影响。因此,在SML/NJ 0.93中 写得简单是可能的 签名S= 信号发生器 打开A 值x:t 结束; 具有相同的效果。
由于这些表单在SML'97中已删除,因此在转换时 SML’90(或SML/NJ 0.93)代码,有必要发现并消除使用 本地和开放式签名,并写出完整类型的路径 对于那些因此被缩写的类型。
在其全部通用性中使用本地规范的任何(非SML/NJ)代码 要达到某种奇怪的效果,必须重写才能实现 以其他方式达到预期效果 [ 数据库管理 :我会的 有兴趣看到这方面的例子]。
1.3.12. 标识符没有重复的规范
1.3.13. 的行为 包括 (Defn vs SML/NJ)