2012-07-31 13 views
5

ocamlプロジェクトで作業中に私が実際に理解していないものが見つかりました。ocamlのモジュラプログラミング

OCaml標準ライブラリのモジュールとListモジュールの両方を使用しているとします。どちらも関数lengthを実装していますが、タイプは異なります。 Listモジュールで 、これはそのタイプです:

length: a' list -> int 

そしてArrayモジュールでは、それはタイプがあります。

length: a' array -> int 

をしかし、私はあなたが私がした同じモジュールで両方のモジュールを使用したかったですopenキーワードを経て、実装:

open List 
open Array 

私は上のlength機能を使用しようとしたときリストでは、コンパイル時にタイプエラーが発生しました。
OCamlは強力な静的型言語なので、私は両方を使用していると宣言して以来、コンパイラがリストモジュールの長さ関数を望んでいないのをなぜ知りませんでした。

+1

"コンパイラがリストモジュールの長さ関数を望んでいない理由は分かっています。なぜなら、私は「はい」を使用していたと宣言していたからですが、' fun s - > length s'この文脈は? –

+0

jrouquieの答えに基づいて、 'a 'array - > int' –

+1

正確には推測しようとした仮想OCamlコンパイラの場合、OCaml型システムには最も一般的な型は1つしかありません関数のために。あなたは、この厄介なことに対するHaskellの解答に興味があるかもしれません。クラスをタイプしてください:http://www.haskell.org/tutorial/classes.html –

答えて

8

OCamlは、そのタイプに基づいて1つの関数または別の関数を選択しません。あなたは

open Array 

を書くとき

モジュールArrayの機能は、同じ名前を持つモジュールListのものをマスキングしています。 後で関数lengthを呼び出すと、OCamlはlengthという名前の関数を探し、Array.lengthを見つけ、この関数に互換性のある型がないと告げる。

普通の方法は、の代わりにList.length(必要な機能であれば)を呼び出すことです。


もっと一般的に言えば、OCamlは型の推論をはるかに困難にするため、特に名前が重複していません(つまり、同じ名前で異なる引数型の2つの関数または演算子があります)。

+2

:モジュールを開くことを避けてください - 読者がどのモジュールが開いているか(そしてどの順序で)覚えていなければならないので、また読者としては、どこから機能が得られたのかをすぐには認識していません(そこからオープンなモジュールです)。 – lambdapower

+2

使用している値/関数の起源が明確であれば、開かれているモジュールは問題ないと付け加えたいと思います。一般的な名前の関数を提供するListやArrayのようなモジュールは開かないでください。printf、fprintfなどの関数が提供されているので、 "open printf"は完全に問題ありません。 –

関連する問題