2016-09-23 7 views
0

が、私はこれらのシグネチャがあるとします。パラメータ化されたファンクタ

module type CharS = sig 
type c 
    type t = BoW | C of c | EoW 

    val compare : t -> t -> int 

    val print : Format.formatter -> t -> unit 
end 

module type GraphemS = sig 

    type c 
    type t 

    val compare : t -> t -> int 
    val print : Format.formatter -> t -> unit 
end 

そして、これら二つのファンクタ:

module MakeDiGraphem (C : CharS) : GraphemS with type c = C.t = struct 

    type c = C.t 
    type t = c * c 

    let compare (cb1, ce1) (cb2, ce2) = 
    let r1 = C.compare cb1 cb2 in 
    if r1 = 0 then 
     C.compare ce1 ce2 
    else r1 

    let print fmt (cb, ce) = 
    Format.fprintf fmt "@[%a%[email protected]]@," C.print cb C.print ce 

end 

module MakeMonoGraphem (C : CharS) : GraphemS with type c = C.t = struct 

    type c = C.t 
    type t = c 

    let compare c1 c2 = C.compare c1 c2 

    let print fmt c = 
    Format.fprintf fmt "@[%[email protected]]@," C.print c 

end 

、私は私がタイプのモジュールを作成できるようになるファンクタをしたいのですが最初のファンクタか2番目のファンクタを持つGraphemS。

module type SizeS = sig 
    type t = int 

    val param : int 
end 

module MakeGraphem (C : CharS) (I : SizeS) : GraphemS with type c = C.t = struct 
    module MonoGraphem = MakeMonoGraphem(C) 
    module DiGraphem = MakeDiGraphem(C) 

    let select_graphem = 
    if I.param = 1 then 
     (module MonoGraphem : GraphemS) 
    else 
     (module DiGraphem : GraphemS) 

    include (val select_graphem) 

end 

しかし、悲しいことに、私が得た:私がやったことはこれです

Error: This expression creates fresh types.

It is not allowed inside applicative functors.

私の質問は、それから、それは私がやりたいと何このエラーは意味ないすることは可能ですか?

答えて

2

基本的に、アプリケーションファンクションアプリケーションインクルードでファーストクラスの計算を行うことはできません。基本的には、タイピング・システムはI.paramが定数であるという保証がないので、ファンクタが常に同じ型を返すことは保証できません。アプリケーションファンクタ(OCamlのデフォルト)は、同じ式に対して常に同じ型を返さなければなりません(ある意味では純粋です)。

あなたはOCamlの4.02以上にある場合、あなたはunit argumentを通じて生成的として、あなたのファンクタを宣言することができます。

module MakeGraphem (C : CharS) (I : SizeS)() : 
      GraphemS with type c = C.t = struct 

トリックを行うための私のお気に入りの道ではなく、引数として適用するファンクタを取得することですIです。

+0

ご返信いただきまして申し訳ありません。署名に問題が多かったため、私はそれを機能させようとしていました。私はファンクタを引数として使用しました(私はそれをやりたいと思いましたが、それは可能ではないと考えていましたので、この "パラメータ"で私のチートです)。 – Lhooq

関連する問題