2016-09-29 56 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 –