anchor.diff:  *)
   
   #r "FSharp.Compiler.Service.dll"
  +open Microsoft.FSharp.Compiler.SourceCodeServices
   open Microsoft.FSharp.Compiler.Interactive.Shell
   
   (**
  
positive.code: コードの評価および実行
  ----------------------
  
  F# Interactiveサービスにはサービスとやりとりするためのメソッドが2つ用意されています。
  1つは `EvalExpression` で、式を評価してその結果を返します。
  結果には戻り値が( `obj` として)含まれる他、値に対して静的に推測された型も含まれます:
  *)
  /// 式を評価して結果を返す
  let evalExpression text =
    match fsiSession.EvalExpression(text) with
    | Some value -> printfn "%A" value.ReflectionValue
    | None -> printfn "結果が得られませんでした！"
  (**
  一方、 `EvalInteraction` メソッドは結果を返しません。
  このメソッドは画面出力機能であったり、F#の式としては不正なものの、
  F# Interactiveコンソールには入力できるようなものなど、
  副作用を伴う命令を評価する場合に使用できます。
  たとえば `#time "on"` (あるいはその他のディレクティブ)や `open System` 、
  その他のトップレベルステートメントなどが該当します。
  *)
  /// 命令を評価して、結果は無視する
  let evalInteraction text = 
    fsiSession.EvalInteraction(text)
  (**
  これら2つのメソッドは文字列を引数にとり、
  それをF#コードとして評価(あるいは実行)します。
  指定するコードの終端に `;;` を入力する必要はありません。
  実行したいコードだけを入力します:
  *)
  evalExpression "42+1"
  evalInteraction "printfn \"bye\""
  
  (**
  `EvalScript` メソッドを使用すると、完全な .fsx スクリプトを評価することができます。
  *)
  /// スクリプトを評価して結果を無視する
  let evalScript scriptPath =
      fsiSession.EvalScript(scriptPath)
  
  evalScript "sample.fsx"
  
  (**
  評価コンテキスト内での型チェック
  
negative.code: *)
  open Microsoft.FSharp.Compiler
  
  // ツールチップを取得する
  checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT) 
  
  checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // シンボル xxx
    
  (**
  'fsi'オブジェクト
  -----------------
  
  スクリプトのコードが'fsi'オブジェクトにアクセスできるようにしたい場合、
  このオブジェクトの実装を明示的に渡さなければなりません。
  通常、FSharp.Compiler.Interactive.Settings.dll由来の1つが使われます。
  *)
  
  let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsi)
  
  (**
  収集可能なコード生成
  --------------------
  
  FsiEvaluationSessionを使用してコードを評価すると、
  .NET の動的アセンブリを生成し、他のリソースを使用します。
  `collectible=true` を渡すことで、生成されたコードを収集可能に出来ます。
  しかしながら、例えば `EvalExpression` から返される `FsiValue` オブジェクトがあって、
  `FsiEvaluationSession` を破棄してしまったに違いないような、
  型を含む未解放のオブジェクト参照がない場合に限ってコードは収集可能です。
  [収集可能なアセンブリに対する制限](https://msdn.microsoft.com/ja-jp/library/dd554932%28v=vs.110%29.aspx#Anchor_1)
  も参照してください。
  
  以下の例は200個の評価セッションを生成しています。 `collectible=true` と `use session = ...`
  の両方を使っていることに気をつけてください。
  
  収集可能なコードが正しく動いた場合、全体としてのリソース使用量は
  評価が進んでも線形には増加しないでしょう。
  *)
  
  let collectionTest() = 
  
      for i in 1 .. 200 do
          let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|]
          use inStream = new StringReader("")
          use outStream = new StringWriter()
          use errStream = new StringWriter()
  
          let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
          use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true)
          
          session.EvalInteraction (sprintf "type D = { v : int }")
          let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i)
          printfn "その %d, 結果 = %A" i v.Value.ReflectionValue
  
  // collectionTest()  <-- このようにテストを実行する