2016-09-27 82 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'呢?它應該如何被該簽名的客戶使用? –