このチュートリアルでは、
Visual Studio
2010
に組み込まれた
F#
の
さまざまな
機能について説明します。
F#
は、関数型プログラミング、オブジェクト指向プログラミング、および探究的プログラミングを組み合わせた
.NET
プラットフォーム用の新しいプログラミング言語です。このチュートリアルでは、
Visual
Studio 2010
への
F#
の統合に重点を置いています。
F#
言語自体のチュートリアルについては、
Visual
Studio 2010
および
.NET Framework 4.0
のトレーニングキット、または
http://msdn.microsoft.com/fsharp
を参照してください。
F#
は汎用プログラミング言語であり、そのツールと共に使用することで、さまざまなアプリケーション、コンポーネント、ツール、およびスクリプトを開発できます。このチュートリアルでは、
F#
言語、ライブラリ、エディタ、プロジェクトシステム、およびデバッガの使用を通して、それぞれの機能について説明します。
チュートリアル
このチュートリアルで使用するシナリオ
で
は、銀行で過去の株価データを分析する開発者
を例にとっています
。この開発者は、非公式で暫定的なデータ分析から作業を開始し、データおよびデータ処理機能全体についての理解を深め、同僚が開発した本格的な分析アプリケーションのコンポーネントに分析結果を統合します。
F#
でのスクリプト作成
1.
新しい
F#
スクリプトを作成します。
[
ファイル
]
メニューの
[
新規作成
]
をクリックし、
[
スクリプト
]
、
[
F#Script
]
(F# スクリプト)を選択します。
"
stockanalysis.fsx
"
という名前を付けて保存します。
2.
F#
から
.NET API
を使用して、
Web
からデータを読み取ります。次のコードを入力します。
- メモ文字列とキーワードは色分けされます。
- メモ
"
"
を入力するたびに、リストが表示されます。
- メモ識別子の途中で
+
Spaceキー、Ctrl
+
kキー、) ""
- メモコード内の識別子の上にマウスポインタを移動すると、がされます。
open System.Net
open System.IO
let url =
"http://ichart.finance.yahoo.com/table.csv?s=MSFT&d=10&e=10&f=2008&g=d&a=2&b=13&c=1986&ignore=.csv"
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let csv = reader.ReadToEnd()
3.
F# Interactive
でコードを実行します。すべてのコードを選択し
(Ctrl
+
A
キーを押し
)
、右クリックして、
[
Send to F#
Interactive
]
(F#
Interactive
に送る
)
をクリックします
(
または
Alt
+
Enter
キーを押します
)
。
- メモまだ表示されていなかった場合は、ツールウィンドウが表示されます。
- メモ
F# Interactive
からの応答は
なり
val url : string =
"http://ichart.finance.yahoo.com/table.csv?s=MSFT&d=10&e=10&f="+[36
chars]
val req : WebRequest
val resp : WebResponse
val stream : Stream
val reader : StreamReader
val csv : string =
"Date,Open,High,Low,Close,Volume,Adj
Close
2008-11-10,21.85,21"+[287779 chars]
>
4.
F# Interactive
でデータを検査します。
F# Interactive
のプロンプトで、「
csv;;
」と入力し、
Enter
キーを押します。さらに、「
csv.Length;;
」と入力し、
Enter
キーを押します。
- メモ
F# interactive
文字列""の値と長さ出力ます。
1986-03-18,29.50,29.75,28.50,28.75,67766400,0.08
1986-03-17,29.00,29.75,29.00,29.50,133171200,0.09
1986-03-14,28.00,29.50,28.00,29.00,308160000,0.08
1986-03-13,25.50,29.25,25.50,28.00,1031788800,0.08
"
>
csv.Length;;
val it
: int = 287846
>
5.
CSV
データを解析する
F#
コードを記述します。エディタで、次のコードを追加します。各行を追加したら、このセクション
で
ここまでに追加したコードを選択し、
Alt
+
Enter
キーを押して部分的な結果を確認します。
- メモ色分け、クイックヒント、複雑な入れ子になった式の途中での""による補完リストは引き続き
- メモコードが不完全であるまたは正しくない
内
随時
- メモパイプライン""とを使用して、データ処理コードの一部を簡単に実行できます。
let prices =
csv.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|','|]))
|> Seq.filter (fun values -> values.Length = 7)
|> Seq.map ( fun values ->
System.DateTime.Parse(values.[0]),
float values.[6])
6.
この機能に名前を付けます。
"url"
の定義から
MSFT
を削除し、
"+ticker+"
に置き換えます。上の行に
let ticker = "MSFT"
を追加します。この新しい
1
行を除くすべてのコードを選択し、
Tab
キーを押します。インデントされたコードブロックの上に、
let loadPrices ticker =
を追加します。インデントされたブロックの末尾に、
prices
を追加します。
- メモ
F#
では、ホワイトスペースインデントには入れ子のレベルを示すという意味があります。
- メモ言語構文軽量コードの抽象化は、
メソッドの抽出
であることを意味します。
open System.Net
open System.IO
let ticker = "MSFT"
let loadPrices ticker =
let url =
"http://ichart.finance.yahoo.com/table.csv?s="+ticker+"&d=10&e=10&f=2008&g=d&a=2&b=13&c=1986&ignore=.csv"
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let csv = reader.ReadToEnd()
let prices =
csv.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|','|]))
|> Seq.filter (fun values -> values.Length = 7)
|> Seq.map ( fun values ->
System.DateTime.Parse(values.[0]),
float values.[6])
prices
7.
この機能を新しい入力に対して使用します。すべてのコードを選択し、
Alt
+
Enter
キー
を押して、
F# Interactive
で実行します。
F# Interactive
のプロンプトで、
さらに次
のティッカーシンボルに対して新しい
"loadPrices"
関数を呼び出します。
"GOOG"
、
"AAPL"
、
"ORCL"
、および
"EBAY"
。
- メモ
F# Interactive
では古い定義は失われず、新しい定義も同時に使用できます。
>
loadPrices "EBAY";;
val it
: seq<System.DateTime * float>
= seq
[(11/10/2008 12:00:00 AM {Date = ...;
<...snip...>
TimeOfDay
= 00:00:00;
Year =
2008;}, 14.72); ...]
>
F#
でのコンポーネント開発
1.
この関数を公開するライブラリプロジェクトを作成します。
[
ファイル
]
、
[
新しいプロジェクト
]
、
[Visual F#]
、
[
ライブラリプロジェクト
]
の順にクリックし、"
StockAnalysis
"という名前の新しいライブラリプロジェクトを作成します。
stokanalysis.fsx
から
Module1.fs
にコードをコピーして貼り付けます。ソリューションエクスプローラで、名前"
Module1.fs
"を"
StockLoader.fs
"に変更します。
- メモ
Visual F#
F#
[
]
プロファイル
[
]
2.
目的の機能を公開する新しい
F#
クラスを作成します。ソリューションエクスプローラで、プロジェクトノードを右クリックし、
[
追加
]
、
[
新しい項目
]
、
[F#
ソースファイル
]
の順にクリックします。
"StockAnalysis.fs"
という名前を付けます。ソリューションエクスプローラで、
Script.fsx
をクリックし、右クリックし
て
、
[
下へ移動
]
をクリックします
(
または
Alt
+
↓
キーを押します
)
。次のコードをこのファイルに入力します。
- メモソリューションエクスプローラでは、新しいファイルは最後に追加され、アルファベット順に並びません。
- メモソリューションエクスプローラでは、コンテキストメニューコマンド、
+
、および
Alt
↓
キーを使用して、ファイルの順序を変更できます。
- メモオブジェクト指向のクラスを
F#
で作成できます。
namespace StockAnalysis
open StockLoader
///
過去の株データを分析する
type StockAnalyzer(lprices, days) =
let prices =
lprices
|> Seq.map snd
|> Seq.take days
///
指定された日数にわたる各ティッカー用の
StockAnalyzer
オブジェクトを
///
構築する
static member GetAnalyzers(tickers, days) =
tickers
|> Seq.map loadPrices
|> Seq.map (fun lprices -> new StockAnalyzer(lprices, days))
member sa.Return =
let lastPrice = prices |> Seq.nth 0
let startPrice = prices |> Seq.nth (days - 1)
lastPrice / startPrice - 1.0
member sa.MeanAndStdDev =
let logRets =
prices
|> Seq.pairwise
|> Seq.map (fun (x,y) -> log (x/y))
let mean = logRets |> Seq.average
let sqr x = x * x
let variance = logRets |> Seq.averageBy (fun x -> sqr (x - mean))
(mean, sqrt
variance)
3.
XML
ドキュメントに関するコメント。ソリューションエクスプローラで、プロジェクトを右クリックし、
[
プロパティ
]
をクリックします。
[
ビルド
]
タブをクリックし、ページ下部の
[
XML
ドキュメント
ファイル
]
チェックボックスをオンにします。
.jpg)
4.
ビルドします。ビルドするには、
Ctrl
+
Shift
+
b
キーまたは
F6
キーを押します。
- メモ出力ディレクトリに、、およびの各ファイルが格納されます。
------
Build started: Project: StockAnalysis, Configuration: Debug Any CPU ------
D:\Program Files\Microsoft F#\v4.0\fsc.exe
-o:obj\Debug\StockAnalysis.dll -g --debug:full --noframework --define:DEBUG
--define:TRACE --optimize- --tailcalls- -r:"D:\Program Files\Microsoft
F#\v4.0\FSharp.Core.dll" -r:"D:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll"
-r:"D:\Program Files\Reference
Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll"
-r:"D:\Program Files\Reference
Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll"
--target:library --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths
--flaterrors StockLoader.fs StockAnalysis.fs
StockAnalysis ->
D:\Users\lukehDDNET\Documents\Visual Studio
10\Projects\StockAnalysis\StockAnalysis\bin\Debug\StockAnalysis.dll
==========
Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
5.
C#
クライアントアプリケーションを追加します。ソリューションを右クリックし、
[
追加
]
、
[
新しいプロジェクト
]
、
[
C#
]
、
[
Visual C#
]
、
[
コンソールアプリケーション
]
の順にクリックします。
"CSharpDriver"
という名前を付けます。
[
参照
]
ノードを右クリックし、
[
参照の追加
]
をクリックします。次に、
[
プロジェクト
]
タブで、
[
StockAnalysis
]
をクリックします。
[
プロジェクト
]
ノードを右クリックし、
[
スタートアッププロジェクトに設定
]
をクリックします。次のコードを
Main
メソッドの本文に入力します。
- メモ
F#
.NET4.0
あり
F#
FSharp.Core.dll
を参照することなく
C#
からネイティブに使用できす。
var tickers = new[] { "MSFT", "GOOG", "ORCL",
"EBAY" };
var analyzers = StockAnalysis.StockAnalyzer.GetAnalyzers(tickers, 365);
foreach (var item in analyzers)
{
Console.WriteLine("Return = {0}, \t Mean = {1}, \t StdDev = {2}",
item.Return, item.MeanAndStdDev.Item1, item.MeanAndStdDev.Item2);
}
6.
デバッグします。ビルド、デバッガの起動、およびステップインを行うには、
F11
キーを押します。
GetAnalyzers
メンバの本文内の
F#
コードにステップインするまで、
F11
キーをさらに数回押します。
- メモ
C#
へのデバッグはシームレスに動作します。
- メモ
"
"
パラメータと
"
"
パラメータの値がローカルウィンドウに表示されます。
- メモ操作を続けて、アプリケーションの残りの部分を評価します。
- メモカーソル行の前まで実行、次のステートメントの設定、ブレークポイントの挿入、ウォッチ式の追加、逆アセンブリを表示などのデバッガのコマンドは、すべて予想どおりに動作します。
.jpg)
F#
での非同期プログラミング
1.
F# PowerPack
。http://msdn.microsoft.com/fsharpで、リンクをクリックして
F# PowerPack
をダウンロードします。
StockAnalysis
プロジェクトで、
[
参照の追加
]
を右クリックし、ディスク上の
FSharp.PowerPack.dll
アセンブリを参照して選択します。
- メモ
F# PowerPack
F#
の便利な拡張機能セットです。
- メモ
F# PowerPack
PowerPack
の便利な非同期プログラミングヘルパをいくつか使用します。
- メモ
F# PowerPack
参照ローカルにコピー"ように設定されています。
[
注
:
このチュートリアル
を
実行
する時点で
F# PowerPack
がまだ
使用できない場合は、
上記の
指示
を実行する
代わりに次の定義を
StockLoader.fs
の先頭に直接追加してください。
type System.Net.WebRequest with
member req.AsyncGetResponse() =
Async.BuildPrimitive(req.BeginGetResponse, req.EndGetResponse)
type System.IO.StreamReader with
member reader.AsyncReadToEnd() = async {
do! Async.SwitchToNewThread ()
let res = reader.ReadToEnd()
do! Async.SwitchToThreadPool ()
return res }
注の終わり
]
2.
非同期ワークフロー。
StockLoader.fs
で次に示す
4
行を変更します。
- メモ非同期コードは同期コードと同じプログラミングスタイルを維持します。
- メモ""キーワードは非同期コードブロックを導入し、
let!
- メモこれらを追加した結果、は、それが実行されるスレッドをブロックせずに実行できる計算式を定義するようになりました。
open System.Net
open System.IO
let ticker = "MSFT"
let loadPrices ticker = async {
let url =
"http://ichart.finance.yahoo.com/table.csv?s="+ticker+"&d=10&e=10&f=2008&g=d&a=2&b=13&c=1986&ignore=.csv"
let req = WebRequest.Create(url)
let! resp = req.AsyncGetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let! csv = reader.AsyncReadToEnd()
let prices =
csv.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|','|]))
|> Seq.filter (fun values -> values.Length = 7)
|> Seq.map ( fun values ->
System.DateTime.Parse(values.[0]),
float values.[6])
return prices }
3.
非同期コードの使用。
StockAnalysis.fs
ファイルを開きます。エラーリストをチェックし、
StockAnalysis.fs
にエラーがあることを確認します。
GetAnalyzers
メンバを次のように変更します。
- メモエラーリストは、エディタで開いているファイルで、コードリファクタリングのガイドとして使用できます。
- メモバックグラウンドでの型チェックによって、適切な修正ヒント
(
seq<async<’a>>
seq<’a>
に変更するために何が必要か得ます。
- メモ
Async.Parallel
、非同期ワークフロー並列処理を導入する方法提供ます
- メモこれらの変更を行うと、すべての証券ティッカーがダウンロードされ、順次ではなく同時に処理されます。の並列処理がされますが、さらに重要な、、使用可能な
I/O
が利用されます
///
指定された日数にわたる各ティッカー用の
StockAnalyzer
オブジェクトを
///
構築する
static member GetAnalyzers(tickers, days) =
tickers
|> Seq.map loadPrices
|> Async.Parallel
|> Async.Run
|> Seq.map (fun lprices -> new StockAnalyzer(lprices, days))
4.
[
Parallel Stacks
]
(
並列スタック
)
デバッグウィンドウ。
StockLoader.fs
の行
"let stream = …"にブレークポイントを設定します。
F5
キーを押して、このブレークポイントまで実行します。メインメニューで、
[
デバッグ
]
、
[
ウィンドウ
]
、
[
Parallel Stacks
]
(
並列スタック
)
の順にクリックして、次に示すウィンドウを開きます。
F5
キーを
数回
(3
~
4
回
)
押します。
- メモ
Parallel Stacks
並列スタックウィンドウで、複数のスレッドが非同期ワークフローでどのように実行されているかを確認できます。
- メモ周期的に
loadPrices
を実行
2
存在
CPU
- メモほとんど常に、スリープ状態、待機状態、または結合状態にあるスレッドが存在します。これはの並列処理を示します。
.jpg)
アプリケーションの配置
1.
複数のターゲット
:
ソリューションエクスプローラで、
F# StockAnalysis
プロジェクトを右クリックし
、
[
プロパティ
]
をクリックします。
[
アプリケーション
]
タブをクリックし、
[
Target Framework
] (
ターゲットフレームワーク
)
の設定を
[
.NET Framework 4.0 Client Profile
]
に変更します。
- メモ
.NET4.0 Client
Profile
は
.NET Framework
.NET
を含みます
- メモターゲットフレームワークを変更するには、プロジェクトを再度読み込む必要があります。
.jpg)
2.
前提条件の設定
:
CSharpDriver
の
[
プロパティ
]
ノードをダブルクリックし、
[
発行
]
タブを開きます。
[
前提条件
]
ボタンをクリックし、
[
Microsoft Visual F#
再配布可能パッケージ
]
チェックボックスをオンにします。
- メモ
F#
F#
で開発されたアプリケーションが実行されるクライアントマシンにインストールする必要がある独立した再配布可能パッケージがあります。
- メモこの再配布可能パッケージは、または
Setup
.jpg)
3.
C#
アプリケーションを
ClickOnce
で配置します。
CSharpDriver
プロジェクトを右クリックし、
[
発行
]
、
[
完了
]
の順にクリックします。発行された
CsharpDriver.exe
を実行します。
.jpg)