我编写的这个练习旨在帮助我理解标准 ML 中的签名、结构和函子。我似乎无法让它工作。仅供参考,我正在使用
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
然后我可以创建一个仿函数来给我一个具有所需类型和属性的结构:
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
据我了解,使用 :> 不透明地赋予签名使其无法访问签名中未明确定义的任何结构内部,但我透明地赋予了 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
尝试访问“empty”和“addList”会产生未绑定的变量错误。
另一方面,尝试在结构之外显式定义 Set 结构并使用其函数会在调用 mag 时出现类型错误:
Error: operator and operand don't agree [tycon mismatch]
operator domain: IntMagSet.object
operand: Set.set
in expression:
IntMagSet.mag X