次の方法で共有


チュートリアル: Visual F# を使用したアプリケーションの作成、デバッグ、および配置

このチュートリアルでは、Visual Studio で .NET Framework 4.5 と共に F# を使用する手順を紹介します。

このチュートリアルでは、米国財務省の金利情報に関するこれまでのデータ分析を例に挙げながら、Visual Studio を使用して F# アプリケーションを記述する方法を説明します。まず F# の対話形式のウィンドウを使用して簡単な分析を行い、次にデータを分析するコードを記述してテストします。その後、C# のフロントエンドを追加して、作成した F# コードを他の .NET 言語と統合する方法を示します。

必須コンポーネント

このチュートリアルを実行するには、次のコンポーネントが必要です。

  • Visual Studio

[!メモ]

お使いのマシンで、Visual Studio ユーザー インターフェイスの一部の要素の名前や場所が、次の手順とは異なる場合があります。これらの要素は、使用している Visual Studio のエディションや独自の設定によって決まります。詳細については、「Visual Studio の設定」を参照してください。

F# スクリプトを作成するには

  1. まず、F# スクリプトを作成します。[ファイル] メニューの [新規作成] をポイントし、[ファイル] をクリックします。[新しいファイル] ダイアログ ボックスで、[インストールされたテンプレート] の一覧で [全般] カテゴリの [スクリプト] をクリックし、[F# スクリプト ファイル] を選択します。[開く] をクリックしてファイルを作成し、RateAnalysis.fsx という名前で保存します。

  2. .NET と F# API を使用して、米国連邦準備銀行のインターネット サイトのデータにアクセスします。次のコードを入力します。

    open System.Net
    open System.IO
    
    let url = sprintf "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H15&series=bcb44e57fb57efbe90002369321bfb3f&lastObs=&from=&to=&filetype=csv&label=include&layout=seriescolumn"
    let req = WebRequest.Create(url, Timeout = 10000000)
    let resp = req.GetResponse()
    let stream = resp.GetResponseStream()
    let reader = new StreamReader(stream)
    let csv = reader.ReadToEnd()
    

    次の点に注意してください。

    • 文字列とキーワードは色分けして表示されます。

    • ピリオド (.) を入力すると、入力候補一覧が表示されます。

    • メソッド名やその他の識別子を Visual Studio によって完成させることができます。これを行うには、識別子の途中でショートカット キー Ctrl + Space または Ctrl +J を使用します。Ctrl + J キーを使用した場合は、入力候補一覧が表示されます。

    • コードで識別子の上にマウス ポインターを置くと、その識別子についての情報を示すツールヒントが表示されます。

    • WebRequest にカーソルがあるときに F1 キーを押すと、関連するドキュメントが表示されます。

    • let にカーソルがあるときに F1 キーを押すと、関連するドキュメントが表示されます。

    • mscorlib.dll、System.dll、および System.Windows.Forms.dll の型と名前空間が既定で参照されます。

    • ここで設定される Timeout 値は、コンストラクター引数ではなく、プロパティです。F# では、この方法でプロパティ値を設定できます。

    • この例の URL をブラウザーにコピーすると、米国連邦準備銀行によって公開されている、日付と金利を含むコンマ区切りの値の一覧が返されます。

  3. ここで、F# Interactive を使用してコードを実行できます。すべてのコードを選択し (マウスを使用するか、Ctrl キーを押しながら A キーを押します)、右クリックして、[対話形式で実行] をクリックします。(または、Alt + Enter キーを押します)。

    • [F# Interactive] ウィンドウがまだ表示されていない場合は、表示されます。

    • コードが正常に実行されます。

    • [F# Interactive] ウィンドウに次の結果が表示されます。

      val url : string =
        "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H1"+[107 chars]
      val req : System.Net.WebRequest
      val resp : System.Net.WebResponse
      val stream : System.IO.Stream
      val reader : System.IO.StreamReader
      
      val csv : string =
        ""Series Description","Market yield on U.S. Treasury securities"+[224219 chars]
      
      >
      
  4. 次に、F# Interactive を使用してデータを調べます。F# Interactive プロンプトで、「csv;;」と入力し、Enter キーを押します。「csv.Length;;」と入力し、Enter キーを押します。次の点に注意してください。

    • データは最新です。

    • F# Interactive は、文字列 csv の値とその長さを表示します。次に例を示します。

      07/10/2009, 3.32
      07/13/2009, 3.38
      07/14/2009, 3.50
      07/15/2009, 3.63
      "
      > csv.Length;;
      val it : int = 224513
      
    • 次の図は、[F# Interactive] ウィンドウを示しています。

      [F# Interactive] ウィンドウ

      [F# Interactive] ウィンドウ

  5. 次に、F# コードを記述して CSV (コンマ区切り値) データを解析します。CSV ファイルという名前は、コンマで区切られた値を含んでいることに由来します。コード エディターで、次のコードを追加します。また、ファイルの先頭に「open System.Globalization」を追加します。各行を追加しているとき、このセクションで追加したコードをその行まで選択し、Alt キーを押しながら Enter キーを押すと、部分的な結果を確認できます。次の点に注意してください。

    • 複雑な入れ子になった式の途中でも、ピリオドを入力すると、IntelliSense によって役立つ情報が表示されます。

    • コードが不完全である (または正しくない) 場合は、コード内の構文エラーとセマンティック エラーが赤い波線で指摘されます。

    • パイプ演算子 (|>) を使用して、パイプラインを作成します。パイプ演算子は、ある式からの戻り値を受け取り、次の行にある関数の引数として使用します。パイプラインと F# Interactive によって、データ処理コードの部分的な実行が簡単になります。

    let interest = 
        csv.Split([|'\n'|])
        |> Seq.skip 8
        |> Seq.map (fun line -> line.Trim())
        |> Seq.filter (fun line -> not (line.EndsWith("ND")))
        |> Seq.filter (fun line -> not (line.Length = 0))
        |> Seq.map (fun line -> line.Split([|','|]))
        |> Seq.map ( fun values ->
            System.DateTime.Parse(values.[0], CultureInfo.CreateSpecificCulture("en-US")),
            float values.[1])
    
  6. ここで、この機能に名前を付けます。url の定義からシリーズ ID bcb44e57fb57efbe90002369321bfb3f を削除し、「%s」に置き換えることで、リテラル文字列を書式指定文字列に変更します。この書式指定文字列の後に「seriesID」を追加します。open ディレクティブを除くすべてのコードを選択し、Tab キーを押します。インデントが設定されたコード ブロックの上に以下のコード行を追加します。

    let loadRates maturity =
        // The following tuples associate various maturity durations, in years,
        // with codes defined for treasury bills by the Federal Reserve.
        let maturitiesMap = Map.ofList [(1, "e30653a4b627e9d1f2490a0277d9f1ac")
                                        (2, "c66ea77a2e8f0919c5133c7633065908")
                                        (5, "fbb02942bfdbff31a479e98bcbe26388")
                                        (10, "bcb44e57fb57efbe90002369321bfb3f")
                                        (20, "a1ebeb6e84ca6389772dd054dc980191")]
        let seriesID = Map.find maturity maturitiesMap
    

    インデントが設定されたコード ブロックの末尾に、「interest」を追加します。次の点に注意してください。

    コードは次のようになります。

    open System.Net
    open System.IO
    
    let loadRates maturity =
        // The following tuples associate various maturity durations, in years,
        // with codes defined for treasury bills by the Federal Reserve.
        let maturitiesMap = Map.ofList [(1, "e30653a4b627e9d1f2490a0277d9f1ac")
                                        (2, "c66ea77a2e8f0919c5133c7633065908")
                                        (5, "fbb02942bfdbff31a479e98bcbe26388")
                                        (10, "bcb44e57fb57efbe90002369321bfb3f")
                                        (20, "a1ebeb6e84ca6389772dd054dc980191")]
        let seriesID = Map.find maturity maturitiesMap
        let url = sprintf "http://www.federalreserve.gov/datadownload/Output.aspx?rel=H15&series=%s&lastObs=&from=&to=&filetype=csv&label=include&layout=seriescolumn" seriesID
        let req = WebRequest.Create(url, Timeout = 10000000)
        let resp = req.GetResponse()
        let stream = resp.GetResponseStream()
        let reader = new StreamReader(stream)
        let csv = reader.ReadToEnd()
    
    
        let interest = 
            csv.Split([|'\n'|])
            |> Seq.skip 8
            |> Seq.map (fun line -> line.Trim())
            |> Seq.filter (fun line -> not (line.EndsWith("ND")))
            |> Seq.filter (fun line -> not (line.Length = 0))
            |> Seq.map (fun line -> line.Split([|','|]))
            |> Seq.map ( fun values ->
                System.DateTime.Parse(values.[0], CultureInfo.CreateSpecificCulture("en-US")),
                float values.[1])
        interest
    
  7. この機能を新しい入力に対して使用します。すべてのコードを選択し、Alt キーを押しながら Enter キーを押して、F# Interactive でコードを実行します。F# Interactive プロンプトで、他の満期金利 (1、2、5) について、新しい loadRates 関数を呼び出します。次の点に注意してください。

    • F# Interactive では、以前の定義は失われませんが、新しい定義が有効になります。

    • 複雑に構造化されたデータが、特別な出力機能によってレンダリングされます。

F# を使用してコンポーネントを開発するには

  • 作成した機能を公開するライブラリ プロジェクトを作成します。[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。[新しいプロジェクト] ダイアログ ボックスで、[インストール済み] の一覧の [Visual F#] をクリックし、[F# ライブラリ] を選択して、新しいライブラリ プロジェクトを作成します。プロジェクトに「RateAnalysis」という名前を付けます。以前に作成したコードを RateAnalysis.fsx からコピーし、Library1.fs に貼り付けます。ファイルの先頭にモジュール宣言 module RateLoader を追加します。ソリューション エクスプローラーで、Library1.fs の名前を RateLoader.fs に変更し、ファイルを保存します。次の点に注意してください。

    • 既定の F# ライブラリ テンプレートには、拡張子が .fs のコード ファイルと、拡張子が .fsx のスクリプトが含まれています。このスクリプト ファイルを使用すると、ライブラリ コードを対話形式でテストできます。
  1. 必要な機能を公開する F# クラスを作成します。ソリューション エクスプローラーで、プロジェクトを右クリックし、[追加] をポイントして、[新しい項目] をクリックします。[新しい項目の追加] ダイアログ ボックスで、[F# ソース ファイル] を選択します。ファイルに「Analyzer.fs」という名前を付けます。ソリューション エクスプローラーScript.fsx を右クリックし、[下へ移動] をクリックします (または、Alt キーを押しながら↓キーを押します)。次のコードを Analyzer.fs に貼り付けます。

    module RateAnalysis.Analyzer
    
    open RateLoader
    
    /// Provides analysis of historical interest rate data.
    type Analyzer(ratesAndDates) = 
        let rates = 
            ratesAndDates
            |> Seq.map snd
    
        /// Construct Analyzer objects for each maturity category.
        static member GetAnalyzers(maturities) = 
            maturities
            |> Seq.map loadRates
            |> Seq.map (fun ratesAndDates -> new Analyzer(ratesAndDates))
    
        member sa.Min =
            let date, minRate = (Seq.minBy (fun (_, rate) -> rate) ratesAndDates)
            (minRate, date.ToString("d"))
    
        member sa.Max = 
            let date, maxRate = (Seq.maxBy (fun (_, rate) -> rate) ratesAndDates)
            (maxRate, date.ToString("d"))
    
        member sa.Current =
            rates |> List.ofSeq |> List.rev |> List.head 
    

    次の点に注意してください。

    • F# では、オブジェクト指向プログラミングの概念がサポートされています。詳細については、「クラス (F#)」、「継承 (F#)」、および F# 言語リファレンスのその他の関連トピックを参照してください。
  2. プロジェクトをビルドするために、Ctrl キーと Shift キーを押しながら B キーを押すか、または F6 キーを押します。次の点に注意してください。

    • プロジェクトが正常にビルドされます。

    • [エラー一覧] ウィンドウには、エラーは表示されません。

    • 出力ディレクトリには、.dll、.pdb、および .xml の各ファイルが作成されます。

    • [出力] ウィンドウには、次のような出力が表示されます。

      ------ Build started: Project: RateAnalysis, Configuration: Debug Any CPU ------
          C:\Program Files (x86)\Microsoft F#\v4.0\fsc.exe -o:obj\Debug\RateAnalysis.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files (x86)\Microsoft F#\v4.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Program.fs RateLoader.fs ValueAnalyzer.fs 
          RateAnalysis -> C:\Users\ghogen\Documents\Visual Studio 10\Projects\RateAnalysis\RateAnalysis\bin\Debug\RateAnalysis.exe
      ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
      
  3. C# クライアント アプリケーションを追加するには、ソリューション ノードのショートカット メニューを開き、[追加] をポイントし、[新しいプロジェクト] をクリックします。[新しいプロジェクト] ダイアログ ボックスで、[インストールされたテンプレート] の一覧の [Visual C#] をクリックしてから、[コンソール アプリケーション] をクリックします。[他の言語] ノードを展開する必要がある場合があります。プロジェクトに「CSharpDriver」という名前を付け、[OK] をクリックします。このプロジェクトの [参照] ノードでショートカット メニューを開き、[参照の追加] をクリックします。[ソリューション] ノードを選択し、[プロジェクト] ノードを選択します。[RateAnalysis] プロジェクトの横にあるチェック ボックスをオンにし、[OK] をクリックします。[CSharpDriver] プロジェクト ノードのショートカット メニューを開き、[スタートアップ プロジェクトに設定] をクリックします。C# アプリケーションの Main メソッドの本体に、次のコードを入力します。

    var maturities = new[] { 1, 2, 5, 10 };
    var analyzers = RateAnalysis.Analyzer.Analyzer.GetAnalyzers(maturities);
    
    foreach (var item in analyzers)
    {
        Console.WriteLine("Min = {0}, \t Max = {1}, \t Current = {2}", item.Min, item.Max, item.Current);
    }
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    

    次の点に注意してください。

    • C# と F# の間で、プロジェクト間参照を追加できます。

    • F# で定義された名前空間と型は、C# で他の型と同じように使用できます。

    • F# のドキュメント コメントを C# の IntelliSense で参照できます。

    • F# API からのタプルの戻り値に C# でアクセスできます。タプルは、.NET Framework 4.5 の Tuple 値です。

  4. アプリケーションをデバッグするために、F11 キーを押してアプリケーションをビルドし、デバッガーでアプリケーションを起動して、実行されるコードの最初の行にステップ インします。F# コードの GetAnalyzers メンバーの本体にステップ インするまで、F11 キーを数回押します。次の点に注意してください。

    • C# コードから F# コードに簡単にステップ インできます。

    • F# の各式は、デバッガーでの 1 つのステップに相当します。

    • [ローカル] ウィンドウに maturities の値が表示されます。

    • 引き続き F11 キーを押していくと、アプリケーションの残りの部分がステップ実行されます。

    • [カーソル行の前まで実行][次のステートメントの設定][ブレークポイントの挿入][ウォッチ式の追加][逆アセンブルを表示] など、デバッガー コマンドはすべて期待どおりに機能します。

アプリケーションを配置するには

  1. デバッグ中の場合は、Shift キーを押しながら F5 キーを押すか [デバッグ] メニューの [デバッグの停止] をクリックして、デバッグを停止します。

  2. CSharpDriver プロジェクトのショートカット メニューを開き、[プロパティ] をクリックします。

  3. プロジェクト デザイナーで、[発行] タブをクリックします。アプリケーションを配置するためのオプションが表示されます。

  4. [発行ウィザード] をクリックします。

    発行ウィザードが起動し、最初の画面で、発行されるファイルの配置場所を指定するよう求められます。

  5. テキスト ボックスで、発行時にアプリケーションのインストール ファイルを配置する場所としてローカル ディスク上の場所を指定するか、[参照] をクリックしてその場所に移動します。

  6. すべての既定値をそのまま使用して、クライアント コンピューターに配布される標準的なセットアップをビルドするには [完了] をクリックし、他の発行オプションを表示するには [次へ] をクリックします。

    セットアップ実行可能ファイルと関連ファイルは、指定した場所に発行されます。

次の手順

F# コードを書き始めるには、「チュートリアル: 初めての F# プログラム」を参照してください。F# の関数について学習するには、「ファースト クラスの値としての関数 (F#)」を参照してください。F# 言語について調べるには、「F# 言語リファレンス」を参照してください。

参照

その他の技術情報

Visual F# のサンプルとチュートリアル

Visual F# のサンプルとチュートリアル