質問

私のモジュールのいくつかには、2つの方法で特定のクラスタイプを実装するグローバルクラスインスタンスが含まれています。 private_methodpublic_method.

が欲しいです MyModule.my_instance # public_method 私のプログラムのどこからでも利用できるようになり、 MyModule.my_instance # private_method 内でのみ利用できるようにします MyModule.

私は次のことを試みました:

class type public_type = object
  method public_method  : int
end ;;

class type private_type = object
  method public_method  : int
  method private_method : int
end ;;

let make_private : unit -> private_type = fun () -> object
  method public_method  = 0
  method private_method = 0
end ;;

module type MY_MODULE = sig
  val my_instance : public_type
end

module MyModule : MY_MODULE = struct
  let my_instance = make_private ()
  let _           = print_int (my_instance # private_method)
end 

ただし、これによりエラーが発生します。

値は一致しません:

val my_instance : private_type

に含まれていません

val my_instance : public_type

たぶん......だろう 強制を手動で書く:

module MyModule : MY_MODULE = struct
  let my_instance = make_private ()
  let _           = print_int (my_instance # private_method)

  let my_instance = (my_instance :> public_type)
end 

しかし、私はこれほど単純なもののコードサイズを2倍にしたくありません。

なぜこれが起こるのか、どのように私がそれを回避できるかについて何か提案はありますか?

役に立ちましたか?

解決

OCAMLには暗黙の強制はありません。多分それは、これらの同じプロパティを備えたいくつかのモジュールがある場合)に強制を加える価値があります:

module Hide(M:sig val my_instance : private_type end) : MY_MODULE =
struct
  let my_instance = (M.my_instance :> public_type)
end

module MyModule = Hide (struct
  let my_instance = make_private ()
  let _           = print_int (my_instance # private_method)
end)

他のヒント

おそらくこれを解決するための最良のテクニックは使用することです プライベート行タイプ Garrigueが説明したように(「プライベートロウタイプ:名前を抽象化する」; 2番目のリンクを投稿できないので調べてください)。これは、明示的なオブジェクトタイプ式で使用できます。

module type MY_MODULE2 = sig
  type t = private < public_method : int; ..>
  val my_instance : t
end ;;

module MyModule2 : MY_MODULE2 = struct
  type t = private_type
  let my_instance = make_private ()
  let _           = print_int (my_instance # private_method)
end  ;;

またはオブジェクトパス(これが必要なものです):

module type MY_MODULE3 = sig
  type t = private #public_type
  val my_instance : t
end ;;

module MyModule3 : MY_MODULE3 = struct
  type t = private_type
  let my_instance = make_private ()
  let _           = print_int (my_instance # private_method)
end  ;;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top