私は再帰的に定義された2つのクラスを1つの順序でコンパイルできますが、別の順序ではコンパイルできません。次のようにコードの簡略化されたバージョンが見える:F#:一般的なメンバは、このプログラムポイントの前に一様でないインスタンス化で使用されました
type Loader() =
member this.Load path =
let ref = Ref()
ref.Wait()
ref
and Ref<'T>(data: obj) =
member this.Foo = 1
member this.Wait() =()
member this.Value = data :?> 'T
エラーがthis.Wait()宣言です。 - しかし、実際のコードは再帰的であることを2つの宣言を必要としない簡易版で実際に再帰のためには必要がないことを
asset.fs(11,21): error FS1198: The generic member 'Wait' has been used at a non-uniform
instantiation prior to this program point. Consider reordering the members so this
member occurs first. Alternatively, specify the full type of the member explicitly,
including argument types, return type and any additional generic parameters
and constraints.
注:以下のようにフルテキストがあります。
エラーメッセージ(つまり、メンバthis.Wait(): unit =()
)に記載されているように、Wait()の型を指定することでこれを解決できますが、なぜこれを行う必要があるのかを理解したいと思います。
質問は、呼び出しの場所での最初の推論のWaitのタイプは何ですか。私はそれがunit - > unit(上記のTomasの答えを参照)であり、unit - > 'aではないことを期待しています。 – zeuxcg
ちょうどチェック - 呼び出し元コードをref.Wait()に変更すると、ユニットは問題を修正します。そうすれば、Waitタイプはユニットになると推測され、後でユニット - >ユニットに制約されます。宣言は認められません。ありがとう! – zeuxcg
@zeuxcg: 'let()= ref.Wait2()'に行を変更してもエラーは修正されませんが、この構造体の拘束力は明示的な ':unit'の拘束力以上でなければなりません。怪しいものが起こっている。コンパイラの型推論には微妙なバグがあると思います。 – kkm