2016-10-21 13 views
1

現在、OCamlにプログラムをビルドしています。次の問題があります。もう一方の型の値を含む2つの型が必要です。その基本的には(しかし、もう少し複雑な)このように:私は、私はそれを使用しようとする場合、私は、私は(そう、この宣言は、エラーをスローしません)前に定義されていませんでした型を参照するが、可能性に気づいOCamlの型定義で後に宣言された型を使用します。

type a = { 
    x: some_other_type; 
    next: b 
};; 

type b = 
    NoA 
    | SomeA of a;; 

それは2つのタイプのbを区別します:aの定義で述べたものと、私が定義したものです。

私はそれを醜い方法で行うことができます知っている:

type 'b a = { 
    x: some_other_type; 
    next: 'b 
};; 

type b = 
    NoA 
    | SomeA of b a;; 

をしかし、私は、私はかなりのように、そのBを見ることが直接できることことを認めざるを得ないが、私は任意のより良い解決策があるかどうか(知っていただきたいと思います再帰型です)。

答えて

4

まず、あなたが例えば、あなたが未定義の型を参照することができますことを、自分の仮定で間違っている、

# type a = { 
    x: some_other_type; 
    next: b 
};; 
     Characters 16-31: 
    x: some_other_type; 
     ^^^^^^^^^^^^^^^ 
Error: Unbound type constructor some_other_type 

したがって、some_other_typeが定義されています。たぶん、あなたのトップレベルのセッションでこれを定義し、それを忘れてしまったでしょう。 some_other_typeを定義すると、Unbound type constructor bというエラーが発生します。したがって、bsome_other_typeの両方が以前に定義されました。新しい型(エイリアスではない)を定義するたびに、新しい型のコンストラクタが作成されます。したがって、type a = A;; type a = Aは2つの異なる(互換性のない)型を定義します。実際には、インタラクティブなトップレベルでのみ同じ名前の2つのタイプを定義することができます(そうでない場合は、タイプ定義を変更する場合はトップレベルを再起動する必要があります)。 OCamlコンパイラでは、同じ構造体に同じ名前の2つの型を定義することはできません。あなたの問題を解決するために

、あなたは例えば、

type some_other_type 

type 'b a = { 
    x: some_other_type; 
    next: 'b 
} 

type b = 
    NoA 
    | SomeA of b a;; 

または

type some_other_type 

type a = { 
    x: some_other_type; 
    next: b 
} 

and b = 
    NoA 
    | SomeA of a;; 

あるいは、多型タイプのいずれかを行うことで、依存関係を壊す、再帰的な型を使用しますか、

type some_other_type 

type 'a b = 
    NoA 
    | SomeA of 'a 

type a = { 
    x: some_other_type; 
    next: a b 
} 
+0

最初のアプローチで 'next: 'b'の代わりに' next:b'を指定するべきではありませんか? – CodenameLambda

+0

いいえ、 'b'はまだ定義されていません。だから、私たちは、 'b'がどんなものであれ、私たちの型' a'をパラメタライズしています。 – ivg

+0

私は最初と最後の間に "and"を付けました。 – CodenameLambda

3

あなたはandを使用して2つのタイプを定義する必要があります:すべての

type a = { 
    x: some_other_type; 
    next: b 
} 

and b = 
    NoA 
    | SomeA of a;; 
+0

これは関数でも機能するので、これを試してください。ありがとう! – CodenameLambda

関連する問題