2016-09-29 9 views
4

Functor引数として受け取った構造体の一部であるデータ型のコンストラクタをStandard MLで再エクスポートすることは可能ですか?Standard MLのfunctor引数からデータ型を再エクスポートする方法

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

ありがとう:私たちは、あなたが以下のプログラムで数子を使用していたときに観測され、同じ動作を得ます。あなたはまったく正しい。私は自分のプロジェクトに夢中になり、タイプが署名に指定されないままになったときにいつも起こるという事実を逃しました。私の特別なケースでは、2つの異なる 'datatype'宣言を持つ2つの異なる' FLAG'構造体を持っているので、実際には署名を定義することはできません。再度、感謝します。 –

+0

私は(希望!)あなたのケースが達成できるはずだと思います!たぶん 'where'の正しい使い方ですか? SMLモジュールシステムは、私が暴露してきた最も刺激的なPL構造の1つですが、多くの場合、多くの方向で制限があり、モジュールシステムが私の望むものではないことを明らかにする障害に遭遇します。私はまだ、どの部分が言語実装によって課せられた制限であるのか、どの部分がうまく形成され、論理的に正しいのか厳しい限界であるのかを把握しようとしています。 –

+1

mixinパターンと呼ばれるパターンを使用して回避することができました。ここでは、単に「ファンクタ」呼び出しの結果を開くだけです。 https://gist.github.com/igstan/c566eecc38784216f1499bfe8d91f4c4 –

関連する問題