1

これは非常に奇妙なことであり、誰かがこれを理解するための洞察を持ってくれることを願っています。

F#2.0(Visual Studio 2010、.Net 4.0を対象)ソリューションがあり、最初に作成した場所で正常に機能しますが、新しいフォルダーにコピーしようとすると(ソース管理にチェックインするため)、 )、ビルド時に非常に奇妙なエラーが発生します。それらは次の線に沿っている傾向があります:

error FS0803: Invalid use of a type name and/or object constructor. If necessary use 'new' and apply the constructor to its arguments, e.g. 'new Type(args)'. Overloads are:  None() : unit.

また

error FS0001: This expression was expected to have type     obj option     but here has type     Some<'a>

これらのエラーは、オプションタイプの使用でのみ発生します。そのような使用法の簡単な例は、次のとおりです。

let asOption e = 
    match e with
    | null -> None
    | _ -> Some(e)

さて、これは元の場所で問題なくコンパイルされるソリューションであることを忘れないでください。Clean / Rebuild、objおよびbinディレクトリの削除、Visual Studionの再起動など、明らかなことを試しましたが、それでも同じです。

参照DLLはどちらの場合もすべて同じであり、GACされたDLLはGACから参照され、非GACされたdllはコピーされ、同じ相対パスから参照されます。楽しみのために、各ソリューションのコンパイルに使用されるFsc.exeの呼び出しの出力ウィンドウのテキストを比較して、どちらの場合もコンパイラーが同じ引数で呼び出されていることを確認しました。当然、そうです。

誰もがこれを引き起こしている可能性があるものについて何か考えがありますか?どういうわけか、GACからFSharp.Core.dllの奇妙なリンボバージョンを取得していますか?私は不運なスティフの中で最も不運なのですか?

4

3 に答える 3

2

したがって、奇妙な症状には同様に奇妙な原因がありました。

私が参照していたDLLの1つ(すべてのプロジェクトにあるユビキタスな「コア」ジャンクドロワーdll)には、コンパイラーとVisualStudioで使用される型推論で問題を引き起こしている拡張メソッドが必要であることがわかりました。

を削除し、open MyProject.Core使用している型への参照を完全修飾名に置き換えると、奇妙なエラーが魔法のように消えます。

したがって、この時点で、2つの質問が残っています。

  1. これを引き起こしている可能性のある、そこにはどのような非常識な拡張メソッドがありますか
  2. 元のソリューション/プロジェクトがこれによる影響を受けなかったのはなぜですか?(これは、参照がFsc.exeの呼び出しに渡された順序に関連している可能性があると思います...しかし、わかりません)。

私は実際に#1の答えを見つけようとするのに十分掘り下げるかもしれません。F#コンパイラで何らかのバグが発生しているのか(疑わしい)、または同僚が拡張メソッドで不自然なことをしているだけなのか(可能性が高い)はわかりません。

更新:誰かがF#の羨望を抱いていてOption<T>、コアプロジェクトでクラスを作成したようです。ほとんど物事を説明します。Fsc.exe呼び出しのインクルードの順序が異なるかどうかを確認するための実験は行っていませんが、それだけだと感じています。

于 2012-06-26T14:47:36.167 に答える
0

F#コンパイラが決定論的であると仮定すると、おそらく環境変数で、F#コンパイラが呼び出される方法に何らかの違いがあるはずです。コマンドラインからMSBuildを実行してみましたか?それは通常、これらの種類のものに役立ちます。

何が起こっているのかを推測すると、F#はコードのさまざまなタイプを推測します。単純な型だけを処理する必要があるように少し制約してみましたか?例えば:

let asOption (e: obj) =
    match e with
    | null -> None
    | _ -> Some(e)

または:

let asOption<'T> (x: 'T) : option<'T> =
    if x :> obj = null then None else Some x

後者は、ジェネリックパラメーターのnull制約を取り除きます。

于 2012-06-26T14:20:52.850 に答える
0

参照はGACからのものであってはならず、からのものでなければなりませんReference Assemblies。あなたが目撃しているfsc.exeコマンドラインを投稿してください、おそらくそれはより多くの光を当てるでしょう。FSharp.Core参照が何らかの形で混乱していると思います(おそらく、参照アセンブリの横にあるsigdata / optdataファイルに関連していますか?)

(ただし、非常に奇妙な症状のポイントです!)

于 2012-06-26T04:23:44.333 に答える