2013-04-29 127 views
0

我编写的练习旨在帮助我理解标准ML中的签名,结构和函子。我似乎无法得到它的工作。仅供参考,我使用为什么我不能访问我的结构的内部ORD_SET结构?

Standard ML of New Jersey v110.75 [built: Sun Jan 20 21:55:21 2013] 

我有一个“对象,你可以计算幅度”以下ML签名:

signature MAG_OBJ = 
sig 
    type object 
    val mag : object -> int 
end 

如果我想给“为int的结构设置与幅度,”我可能有一个结构的有序INT与标准库的ORD_SET签名使用方法如下:

structure OrderedInt : ORD_KEY = 
struct 
    type ord_key = int 
    val compare = Int.compare 
end 

然后,我可以创造一个仿函数给我想要的类型和PR的结构operties:

functor MakeMagSet(structure ELT : ORD_KEY) : MAG_OBJ = 
struct 
    structure Set : ORD_SET = RedBlackSetFn(ELT) 
    type object = Set.set 
    val mag = Set.numItems 
end 

到目前为止好(一切编译,至少)。现在我为我的OrderedInt结构创建结构的实例,我上面提出:

structure IntMagSet = MakeMagSet(structure ELT = OrderedInt) 

但是当我尝试使用它(创建一组,并计算其大小),我得到一个错误:

val X = IntMagSet.Set.addList(IntMagSet.Set.empty, [0,1,2,3,4,5,6,7,8,9]) 

给出了错误:

Error: unbound structure: Set in path IntMagSet.Set.empty.addList 

据我了解,归咎于不透明的签名使用:>使得它如此一个无法访问未在签字:明确定义的任何内部结构e,但是我透明地赋予了MAG_OBJ,所以我应该可以访问Set结构,对吗?我在这里错过了什么?

[编辑]

即使重写特异性结合我想要的结构功能的仿函数是没有好处:

functor MakeMagSet(structure ELT: ORD_KEY) : MAG_OBJ = 
struct 
    structure Set : ORD_SET = RedBlackSetFn(ELT) 
    type object = Set.set 
    val mag = Set.numItems 
    val empty = Set.empty 
    val addList = Set.addList 
end 

尝试访问“空”和“addList”给绑定变量的错误。

在另一方面,试图明确定义设置结构的结构之外,并使用其功能提供了在调用MAG类型错误:

Error: operator and operand don't agree [tycon mismatch] 
    operator domain: IntMagSet.object 
    operand:   Set.set 
    in expression: 
    IntMagSet.mag X 
+0

刚刚意识到我不能说“IntMagSet.Set.empty.addList”,因为我很傻,太习惯了面向对象的风格。我认为这里仍然存在问题,但我必须编辑该问题。 – JeremyKun 2013-04-29 00:24:43

回答

1

我想这是因为你明确地说,类型MakeMagSet作出MAG_OBJ,其签名不包含Set。如果你已经摆脱了: MAG_OBJMAG_OBJ包括ORD_SET,那么它将起作用。

+0

让每个MAG_OBJ都包含一个ORD_SET是没有意义的,因为如果我想对不是集合的东西“计算大小”会怎样? – JeremyKun 2013-04-29 02:25:54

+0

看来,put:MAG_OBJ不会简单地验证生成的结构是否符合接口,但会限制它执行此操作。删除:MAG_OBJ确实解决了这个问题。现在,如果我使用它,例如另一个函数,我仍然可以放:MAG_OBJ并使用mag函数,但是我不能再引用底层集合。这让我想知道为什么函子中的类型归属甚至是一个特征;它使我的结构完全无用! – JeremyKun 2013-04-29 13:46:49