anchor.diff:  コードの評価および実行
   ----------------------
   
  -F# Interactiveサービスにはサービスとやりとりするためのメソッドが2つ用意されています。
  -1つは `EvalExpression` で、式を評価してその結果を返します。
  -結果には戻り値が( `obj` として)含まれる他、値に対して静的に推測された型も含まれます:
  +F# Interactiveサービスにはコードを評価するためのメソッドがいくつか用意されています。
  +最初の1つは `EvalExpression` で、式を評価してその結果を返します。
  +結果には戻り値が( `obj` として)含まれる他、値に対して静的に推論された型も含まれます:
   *)
   /// 式を評価して結果を返す
   let evalExpression text =
     match fsiSession.EvalExpression(text) with
     | Some value -> printfn "%A" value.ReflectionValue
     | None -> printfn "結果が得られませんでした！"
  -(**
  -一方、 `EvalInteraction` メソッドは結果を返しません。
  -このメソッドは画面出力機能であったり、F#の式としては不正なものの、
  -F# Interactiveコンソールには入力できるようなものなど、
  +
  +(**
  +これは引数に文字列を取り、それをF#コードとして評価(つまり実行)します。
  +*)
  +evalExpression "42+1" // '43' を表示する
  +
  +(**
  +これは以下のように強く型付けされた方法で使うことができます:
  +*)
  +
  +/// 式を評価して、強く型付けされた結果を返す
  +let evalExpressionTyped<'T> (text) =
  +    match fsiSession.EvalExpression(text) with
  +    | Some value -> value.ReflectionValue |> unbox<'T>
  +    | None -> failwith "結果が得られませんでした！"
  +
  +evalExpressionTyped<int> "42+1"  // '43' になる
  +
  +
  +(**
  +`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"
  +fsiSession.EvalInteraction "printfn \"bye\""
  +
  +
  +(**
  +`EvalScript` メソッドを使用すると、完全な .fsx スクリプトを評価することが出来ます。
  +*)
  +
  +File.WriteAllText("sample.fsx", "let twenty = 10 + 10")
  +fsiSession.EvalScript "sample.fsx"
  +
  +(**
  +例外処理
  +--------
  +
  +コードに型チェックの警告やエラーがあった場合、または評価して例外で失敗した場合、
  +`EvalExpression` 、 `EvalInteraction` そして `EvalScript` は不器用です。
  +これらのケースでは、 `EvalExpressionNonThrowing` 、 `EvalInteractionNonThrowing`
  +そして `EvalScriptNonThrowing` を使うことが出来ます。
  +これらは結果と `FSharpErrorInfo` 値の配列の組を返します。
  +これらはエラーと警告を表します。結果の部分は実際の結果と例外のいずれかを表す
  +`Choice<_,_>` です。
  +
  +`EvalExpression` および `EvalExpressionNonThrowing` の結果部分は
  +オプションの `FSharpValue` 値です。
  +その値が存在しない場合、式が .NET オブジェクトとして表現できる具体的な結果を
  +持っていなかったということを指し示しています。
  +この状況は実際には入力されたどんな通常の式に対しても発生すべきではなく、
  +ライブラリ内で使われるプリミティブ値に対してのみ発生すべきです。
  +*)
  +
  +File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0")
  +let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx"
  +
  +// 結果を表示する
  +match result with 
  +| Choice1Of2 () -> printfn "チェックと実行はOKでした"
  +| Choice2Of2 exn -> printfn "実行例外: %s" exn.Message
  +
  +
  +(**
  +は次のようになります:
  +
  +    実行例外: Operation could not be completed due to earlier error
  +*)
  +
  +// エラーと警告を表示する
  +for w in warnings do 
  +   printfn "警告 %s 場所 %d,%d" w.Message w.StartLineAlternate w.StartColumn
  +
  +(**
  +は次のようになります:
  +
  +    警告 The type 'float' does not match the type 'char' 場所 1,19
  +    警告 The type 'float' does not match the type 'char' 場所 1,17
  +
  +式に対しては:
  +*)
  +
  +
  +let evalExpressionTyped2<'T> text =
  +   let res, warnings = fsiSession.EvalExpressionNonThrowing(text)
  +   for w in warnings do 
  +       printfn "警告 %s 場所 %d,%d" w.Message w.StartLineAlternate w.StartColumn 
  +   match res with 
  +   | Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T>
  +   | Choice1Of2 None -> failwith "null または結果がありません"
  +   | Choice2Of2 (exn:exn) -> failwith (sprintf "例外 %s" exn.Message)
  +
  +evalExpressionTyped2<int> "42+1"  // '43' になる
  +
  +
  +(**
  +並列実行
  +--------
  +
  +デフォルトでは `EvalExpression` に渡したコードは即時実行されます。
  +並列に実行するために、タスクを開始する計算を投入します:
  +*)
  +
  +open System.Threading.Tasks
  +
  +let sampleLongRunningExpr = 
  +    """
  +async { 
  +    // 実行したいコード
  +    do System.Threading.Thread.Sleep 5000
  +    return 10 
  +}
  +  |> Async.StartAsTask"""
  +
  +let task1 = evalExpressionTyped<Task<int>>(sampleLongRunningExpr)  
  +let task2 = evalExpressionTyped<Task<int>>(sampleLongRunningExpr)
  +
  +(**
  +両方の計算がいま開始しました。結果を取得することが出来ます:
  +*)
  +
  +
  +task1.Result // 完了後に結果が出てくる (最大5秒)
  +task2.Result // 完了後に結果が出てくる (最大5秒)
   
   (**
   評価コンテキスト内での型チェック
  
positive.code: *)
  open Microsoft.FSharp.Compiler
  
  let identToken = Parser.tagOfToken(Parser.token.IDENT("")) 
  checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], identToken) // a tooltip
  
  let symbolUse = 
      checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) 
      |> Async.RunSynchronously
    
  (**
  例外処理
  --------
  
  コンパイルエラーをもっと洗練された形で処理して、
  使い勝手のよいエラーメッセージを出力させたい場合には
  以下のようにするとよいでしょう:
  *)
  
  try 
    evalExpression "42 + 1.0"
  with e ->
    match e.InnerException with
    | null -> 
        printfn "式 (%s) の評価時にエラーが発生しました" e.Message
    //| WrappedError(err, _) -> 
    //    printfn "(ラップされた)式 (%s) の評価時にエラーが発生しました" err.Message
    | _ -> 
        printfn "式 (%s) の評価時にエラーが発生しました" e.Message
  
negative.code: たとえばまず宣言を評価します:
  *)
  
  fsiSession.EvalInteraction "let xxx = 1 + 1"
  
  (**
  
  