2011-07-17 21 views
3

Ocamlの" let .. and ... "には" type "と同じ種類のスコープがありません...と... ":Ocamlの "type ...と" let "と" let ... and "のスコープの不一致

folowing 1ではないスコープで

# let v1 = v2 
and v2 = 3;; 

    Characters 9-11: 
    let v1 = v2 
      ^^ 

Error: Unbound value v2 
でV2、これ以下の1が間違っているT1と同じスコープでOK、T2

# type t1 = t2 
and t2 = int;; 

です

「レック」は機能しません...

# let rec v1 = v2 
and v2 = 3;; 

    Characters 13-15: 
    let rec v1 = v2 
       ^^ 
Error: This kind of expression is not allowed as right-hand side of `let rec' 

なぜ「タイプ...」と「レット...」の間でスコープが一致しないのですか?ありがとうございました。

答えて

9

型は暗黙的に再帰的です。 "let"と同じ効果を得たい場合は、 "let rec .. and"を使用してください。

理想的な言語では、バインディングフォームには2つのバージョン(再帰的と非再帰的)が必要です。 Camlのletの場合は、letlet recです。非再帰型バインドのアクセス可能な形式はありません。デフォルトである必要はありません。たとえtype nonrec ...でもそうです。これはCaml構文の欠陥です。非再帰型定義ができないことによる悪影響は、たとえばin this blog postとなります。

2番目の例では、これは有効範囲ではなく、特定の再帰的定義の妥当性とそれ以外の妥当性です。これは完全に直交する問題です(再帰的な定義が有効なocaml manualを参照してください)。let recは、ここで目的とするものを範囲指定します。

+1

タイプは暗黙的に*等価です*。 * isorecursive *型を取得するには、コンパイラで '-rectypes'フラグを使用する必要があります。ここで認識される不一致は構文上のほのぼのに過ぎず、実際にはそれを形作る価値がありません。 'let ... and ... in ...'構造のように、 'nonrec ... and ...'構造体が言語の中に本当に必要ではありません。 –

+1

@james:私はあなたが間違っていると思う、 '-rectypes'は等価性(名前とその展開の間の平等)を可能にしますが、標準代数的データ型は等価(アイソモルフィズム、コンストラクタによって媒介されます。これはスコープの質問とは何も関係ありません(スコープ内で利用可能なこの名前ですか?)。 'nonrec'問題については、リンク先のブログ記事を読んでください。これは、強制的に再帰的な型定義によって引き起こされる実際の不快感を示しています。 – gasche

+0

後継の場合: 'type nonrec'は今や事です。 –