2012-04-03 5 views
10

私はOCaml Moduleでかなり新しく、 "include"と "open"の両方を組み合わせずに独自のモジュールを使用することはできませんでした。 署名を別の.mliファイルに入れようとしましたが、成功しませんでした。 I以下OCamlモジュール:包含して開きますか?

私は唯一の「開く」を使用する必要があり、あるいはのみ "を行うために必要なものを私は

ocamlc -o main Robot.ml main.ml 

でコンパイルしようとしていることを、実施例を最小に(ではない)が示されていますインクルード "しますが、両方を含めることはできませんか?


ファイル "Robot.ml":

module type RobotSignature = 
sig 
    val top: unit -> unit 
end 

module Robot = 
struct 
    let top() = 
     begin 
     Printf.printf "top\n" 
     end 
    (* Should not be visible from the 'main' *) 
    let dummy() = 
     begin 
     Printf.printf "dummy\n" 
     end 
end 

ファイル "main.ml"(動作しない):

open Robot;; 

top(); 

ファイル "main.ml"(作業):

include Robot;; 
open Robot;; 

top(); 
+0

あなたの質問に対する回答があると思います。 [コンパイル単位](http://caml.inria.fr/pub/docs/manual-ocaml/manual020.html)も参照してください。しかし、一度あなたは 'オープン'が何を理解してください。それを使用しないでください。コードを理解するのが難しくなります。 –

+0

私は通常は同意しますが、その場合、初心者(特にOCamlに限定されません)に基本プログラミングを教えるための簡単な「ロボットライブラリ」を提供することが目的です。だから私は可能な限りRobot.top()構文を避けることを好むでしょう。 –

+0

初心者が実際に演じているオブジェクトを明示的に表現することは、実際にはそれをはるかに過小評価すると思います。とにかく[open](http://caml.inria.fr/pub/docs/manual-ocaml/manual019.html#@manual.kwd170)と[include]のドキュメントを見たいかもしれません。 http://caml.inria.fr/pub/docs/manual-ocaml/manual019.html#@manual.kwd171)。 –

答えて

11

あなたは2つのレベルのロボットを持っています。ロボットrobot.mlファイル内で明示的にモジュール "ロボット"を呼び出したので、Robotを開き、Robot.top()を呼び出す必要があります。 robot.mlファイル内のものは、すでにRobotモジュールの内部に暗黙的に置かれています。

robot.mlで余分な 'module Robot'宣言を取り除くことができます。

robot.mlはなる:

module type RobotSignature = 
sig 
    val top: unit -> unit 
end 


let top() = 
    begin 
     Printf.printf "top\n" 
    end 

あなたのmain.ml.でそれを持っているとして、それが動作するはずです

下記のコメントに基づいて更新します。「ロボットを開く」ときにrobot.mlのすべてが表示されるようになったら、外部から利用できる機能を指定するrobot.mliファイルを定義できます。その後のはあなたを言わせ

val top: unit -> unit 

を:たとえば、あなたがrobot.mlにヘルパーと呼ばれる機能を追加しましょう:

let top() = 
    begin 
    Printf.printf "top\n" 
    end 

let helper() = 
    Printf.printf "helper\n" 

...と、以下のように、あなたはあなたのrobot.mliを定義しますメインからヘルパーに電話しよう。ミリリットル:次に

open Robot;; 

top(); 
(* helper will not be visible here and you'll get a compile error*) 
helper() 

あなたがエラーを取得しますコンパイルしよう:

$ ocamlc -o main robot.mli robot.ml main.ml 
File "main.ml", line 4, characters 0-6: 
Error: Unbound value helper 
+0

実際、署名はすべてがメインから見えるので効果がありません。私は「2つのレベルのロボット」を理解しましたが、有用な署名を維持しながらそれを修正する方法は知らなかった。 –

+0

Robotモジュール内のものだけがmain内に表示されるようにするには、エクスポートするものをエクスポートするrobot.mliファイルを定義します(これを表示するには上記の回答を編集します)。 – aneccodeal

5

あなたがこれを行うには、2つの方法があります。

  • まず、あなたを制約することができます適切な署名であるサブ構造:

    module Robot : RobotSignature = struct ... end 
    

    が続いmain.mlに、あなたがopen Robot.Robot行うことができます:最初のRobotrobot.mlに関連したコンパイル単位を意味し、二Robotはあなたにも含むrobot.mliを1つのレベルを削除し、作成することができますが、robot.ml

  • 内で定義されているサブモジュールである。

    val top: unit -> unit 
    

    robot.ml含む:

    let top() = 
        Printf.printf "top\n" 
    
    (* Should not be visible from the 'main' *) 
    let dummy() = 
        Printf.printf "dummy\n" 
    

    を使用してモジュールをコンパイルし、次にmain.mlopen Robotを単に使用してモジュールをコンパイルできます。

+0

「Robot」を開くのではなく、「Robot.top()」を呼び出す方がよいでしょう。 –

+0

'' 'Robot.Robot.top' ''が長すぎて頻繁に使用されない場合は、 '' 'let R = Robot.Robot in R.top' '' – lambdapower

関連する問題