2016-09-27 26 views
2

如何引用从函子的结果派生类型的结构中使用的签名中的类型。下面是使用聚解释一个例子:引用涉及函子签名结果的类型

> signature Res = sig type f end; 
signature Res = sig type f end 
> functor F (A: sig type t end) : Res = struct datatype f = None | Some end; 
functor F (A: sig type t end): Res 
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end; 
structure S: sig type t = A.f list end 

首先,我不明白为什么A.f显示了在得到的签名时,它是局部的结构。其次,我如何创建一个符合这个结构S的签名?

像这样的东西不起作用:

signature SSig = sig type t = F(struct type t = int end).t list end 

而且,如果F型是int,而不是数据类型,不知何故Ş最终意识到f是一个int,而不是它被签名隐藏。这看起来不像合理的行为,即使使用不透明签名不显示int。

> functor F (A: sig type t end) : Res = struct type f = int end; 
functor F (A: sig type t end): Res 
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end; 
structure S: sig type t = int list end 
> functor F(A: sig type t end):> Res = struct type f = int end; 
functor F (A: sig type t end): Res 
> structure S = struct local structure A = F(struct type t = int end) in type t = A.f list end end; 
structure S: sig type t = A.f list end 

回答

2

我对你的第一个问题没有真正的答案,只是一个猜测,所以我不会对此发表评论。安德烈亚斯罗斯伯格可能会澄清那里的东西:)

关于你的第二个问题。我不明白你为什么要在签名中实例化一个仿函数。也许你想要这个?

signature Res = 
    sig 
    type f 
    end 

signature SSig = 
    sig 
    structure R : Res 
    type t = R.f list 
    end 

然后,谁就实现SSig是免费分配调用FR子结构的结果。

关于你的最后一点。除非您不透明地实现签名,否则类型不会隐藏。

+0

我担心我可能不得不这样做。问题是我不希望在SSig中使类型t不透明,但是我也不想让R包含在签名中,因为我不希望消费者访问它。我可以用一个不透明类型f = R.f来做类似的事情,但是我必须将其包含在签名中,并且再次使签名变得混乱。最后,我很困惑,因为Res没有给出f的类型定义。但我猜想因为F不使用不透明签名,SML可以将其用于S中。 – eatonphil

1

为什么A.f在结构本地时显示在结果签名中。

这似乎是Poly/ML的一个神器。 Moscow ML似乎不漏的名字:

Moscow ML version 2.10 
Enter `quit();' to quit. 
- signature Res = sig type f end; 
> signature Res = /\f.{type f = f} 
- functor F (A: sig type t end) : Res = 
    struct 
    datatype f = None | Some 
    end; 
> functor F : !t.{type t = t}->?=f.{type f = f} 
- structure S = 
    struct 
    local structure A = F(struct type t = int end) 
    in type t = A.f list 
    end 
    end; 
> New type names: =f 
    structure S : {type t = f list} 

我怎么能是指一种类型,在派生从仿函数的结果类型结构中使用的签名?

(评论)问题是我不想让SSig中的类型t不透明,但我也不想在签名中包含R,因为我不希望消费者有权访问到它。我可以用一个不透明类型f = R.f来做类似的事情,但是我必须将其包含在签名中,并且再次使签名变得混乱。

Drup最近回答how to decide whether to parameterize on the type-level or the module-level when designing modules讨论单模化输入类型的缺点。

当所有R都包含t类型时,是不是“使SSig中的t不透明”和“不包含SSig的签名中的R”等价?也许Res包含比t更多的东西,在这种情况下,您可以提供structure R : sig type t end。或者,也许约努茨的回答的这种变化是可取:

signature Res = 
sig 
    type t (* rather than structure R *) 
    type f = t list 
end 

functor F (A : sig type t end) : Res = 
struct 
    type t = A.t 
    type f = t list 
end 

structure S = F(struct type t = int end) 

我不确定如何避免type f = t list重复。

+1

不重复'type f'是关键。在我的真实世界的代码中,'type f'是应用于String结构的RedBlackTree仿函数的结果。这会产生一个类型为t的结果StringMap结构。我唯一的选择似乎是在结构中创建一个设置为StringMap.t的“type sm”,或者将签名的结构REDBLACKTREERES添加到签名中。但是,我不想让这些中的任何一个真正出现在签名中。我已经到了让我感到困惑的地步,你为什么要引用附加在结构上的类型而不是签名。我只想说REDBLACKTREERES.t。 – eatonphil

+1

@eatonphil'REDBLACKTREERES.t'的问题是函子在SML中是生成的,这意味着使用同一个函数创建的两个不同结构的类型't'不会被视为相等。这就是为什么类型必须来自结构而不是签名。 –

+0

@eatonphil为什么你想暴露'类型f'呢?它应该如何被该签名的客户使用? –