http://code.google.com/p/fsharp-typeclasses/ てきな型クラスを使おうとすると、コンパイラがNullReferenceExceptionを吐いて落ちることがある。 VS2010でもVS11betaでも再現する。
-
2つのライブラリプロジェクト(TypeClassLibとClientとする)を用意する
-
TypeClassLibにSystem.XmlとSystem.Xml.Linqへの参照を追加する
-
ClientにTypeClassLibへの参照を追加する
-
TypeClassLibに以下のコードを追加する
module TypeClassLib open System.Xml.Linq type Foo = Foo with static member (?<-) (_, _: Foo, _: string) = () static member (?<-) (_, _: Foo, _: XElement) = () let inline f (a: ^a ) = () ? (Foo) <- a
-
Clientに以下のコードを追加する
let a = TypeClassLib.f ""
-
この状態でビルドすると内部エラーが発生
-
XElementをintやStringBuilder等に変更すると内部エラーは発生しない
-
XElementをXNameに変更すると内部エラーは発生しない
-
XElementを直接使わず、
type X = X of XElement
としてXElementをXに変更すると内部エラーは発生しない
-
XElementをXmlDocumentに変更すると内部エラーは発生しない
-
http://igeta-diary.blogspot.jp/2011/12/build-your-next.html などを参考に、F#のコンパイラをビルドする
-
Dドライブ直下にfsharpディレクトリを作ったとして、src/all-vs2010.slnを開いてTypeClassLibとClientプロジェクトを上の「手順」を参考に作成
-
Clientプロジェクトはアンロードしておく
-
Fscプロジェクトのプロパティを開き、デバッグタブの引数の欄に以下を参考にコマンドライン引数を追加
-r System.Xml -r System.Xml.Linq -r D:\fsharp\src\TypeClassLib\bin\Debug\TypeClassLib.dll D:\fsharp\src\Client\Module1.fs
-
ビルド
-
tast.fsの1340行目が例外を発生させる場所なので、とりあえずそこにブレークポイントはっておく
-
F5でデバッグ実行して、呼び出し履歴とか駆使してLet's調査
注意点としては、Proto/cli/4.0/bin/Microsoft.FSharp-proto.targetsがないとプロジェクトが開けないので、all-vs2010.slnを開く前にちゃんとビルドしておくこと。