2016-09-29 54 views
4

标准ML中是否有可能重新导出作为函数参数接收的结构的一部分的数据类型的构造函数。某些代码可能会使这更容易理解:如何从标准ML中的函数参数中重新导出数据类型标准ML

signature FLAG = 
    sig 
    type t 
    end 

signature MEMBER = 
    sig 
    structure Flag : FLAG 
    end 

functor Member(F : FLAG) : MEMBER = 
    struct 
    structure Flag = F 
    end 

structure M = 
    Member(struct 
    datatype t = 
     FLAG_1 
    | FLAG_2 
    end) 

val flag1 = M.Flag.FLAG_1; 
(* Error: unbound variable or constructor: FLAG_1 in path M.Flag.FLAG_1 *) 

上面的例子可以不作任何形式的实际意义,但它是我在我的一个项目中遇到的问题,只是一个淡化的版本。

回答

4

如果我正确理解了这种情况,FLAG签名中的未配置类型规范就会使t不透明,因此对于实现FLAG的结构之外的任何内容都不可访问。

一般来说,在SML中,如果一个签名指定了一个模块的接口,那么该模块中可以从外部访问的唯一部分是在签名中明确描述的部分。正如你可能知道的那样,如果你为某个模块指定了一个接口,那么只有你在签名中显式声明的那些函数和值才能使用;所有被省略的部分都被封装在模块内部。同样的原则在type t的原因是在这里工作:由于签名没有给出任何有关如何构成这种类型的帐户,没有关于它的信息可用。

所以你可以轻松地将作为参数给定的模块中的值构造函数重新导出到函数,前提是您已将这些构造函数包含在该模块接口的规范中。例如,

signature FLAG = 
sig 
    datatype t = FLAG_1 | FLAG_2 
end 

signature MEMBER = 
sig 
    structure Flag : FLAG 
end 

functor Member(F : FLAG) : MEMBER = 
struct 
    structure Flag = F 
end 

structure M = 
Member(struct 
     datatype t = 
       FLAG_1 
       | FLAG_2 
     end) 

然后

- val a = M.Flag.FLAG_1; 
val a = FLAG_1 : ?.t 

采取这里要注意的最重要的一点,大概是这样的:在模块中值构造的交通不便实施FLAG拥有一切做的方式界面被指定,并且与这里显示为functor Member的参数无关。我们让你当你使用仿函数与以下程序观察到相同的行为:

signature FLAG = 
sig 
    type t 
end 

structure F : FLAG = 
struct 
    datatype t = 
      FLAG_1 
      | FLAG_2 
end 

然后

[opening ~/Programming/sml/scratch/scratch.sml] 
signature FLAG = sig type t end 
structure F : FLAG 
val it =() : unit 
- F.FLAG_1; 
stdIn:63.1-63.9 Error: unbound variable or constructor: FLAG_1 in path F.FLAG_1 
+2

感谢。你是完全正确的。我对自己的项目感到厌倦,错过了在签名中未指定类型时发生的事实。在我的具体情况中,我有两个不同的'FLAG'结构,有两个不同的'datatype'声明,所以我不能真正定义一个签名。再次感谢。 –

+0

我想(希望!)你的情况应该能够实现!也许正确使用'where'? SML模块系统是我已经接触到的最令人兴奋的PL构造之一,但是经常和在许多方面,我感觉有局限性并遇到障碍,使得它明确表示模块系统不是我想要的。我仍然试图确定哪些部分是语言实施所强加的限制,哪些部分是良构和逻辑正确性的严格限制。 –

+1

我能够通过使用一种我称之为mixin模式的模式来解决这个问题,我只是简单地'打开'functor'调用的结果。 https://gist.github.com/igstan/c566eecc38784216f1499bfe8d91f4c4 –