ML模块系统的一个真正重要特征是签名中不透明归属和生成类型声明之间的相互作用:
Poly/ML 5.7.1 Release
> structure O :> OPTION = Option;
structure O: OPTION
> O.NONE = Option.NONE;
poly: : error: Type error in function application.
Function: = : ''a O.option * ''a O.option -> bool
Argument: (O.NONE, Option.NONE) : ''a O.option * 'b option
Reason:
Can't unify ''a O.option (*Created from opaque signature*) with
'a option (*In Basis*) (Different type constructors)
Found near O.NONE = Option.NONE
Static Errors
想象一下,当我发现至少在Poly / ML中,它对列表不起作用时,我感到惊讶和失望:
> structure L :> LIST = List;
structure L: LIST
> L.nil = List.nil;
val it = true: bool
定义是否允许此行为?
答案 0 :(得分:4)
检查基础库的Mlton和Polyml实现,我们看到列表是在结构/签名之外定义的,只是在那里引用。选项不是这种情况,它在结构/签名中定义。
使用Polyml实现作为示例,我们看到LIST签名引用了先前在顶层定义的列表类型,并且OPTION签名在本地定义了选项类型:
function treeDepth(tree)
{
if (tree === null)
return 0;
else
{
/* compute the depth of each subtree */
let leftDepth = treeDepth(tree.left);
let rightDepth = treeDepth(tree.right);
/* use the larger one */
if (leftDepth > rightDepth)
return(leftDepth+1);
else return(rightDepth+1);
}
}
Mlton实施:
https://github.com/MLton/mlton/blob/master/basis-library/list/list.sml
https://github.com/MLton/mlton/blob/master/basis-library/general/option.sml
https://github.com/MLton/mlton/blob/master/basis-library/list/list.sig
https://github.com/MLton/mlton/blob/master/basis-library/general/option.sig
Polyml实现:
https://github.com/polyml/polyml/blob/master/basis/List.sml
https://github.com/polyml/polyml/blob/master/basis/ListSignature.sml
https://github.com/polyml/polyml/blob/master/basis/Option.sml
为了完整性 - sml基础库文档在List模块中说明了以下内容:
列表类型被视为原始类型,并在顶级环境中定义。为了保持一致性,这是反弹。
Option的文档中没有这样的说明,所以我假设上述内容是他们的意思。