この投稿は、仕事でF#を低リスクかつ段階的に使う方法に関するシリーズの結論です。

最後に、コアや重要なコードに影響を与えることなく、F#がさまざまな開発タスクの周辺でどのように役立つかについて、いくつかの方法を見ていきます。

シリーズの内容

本題に入る前に、26の方法の完全なリストを示します:

パート1 - F#を使って対話的に探索し開発する

1. F#を使って.NETフレームワークを対話的に探索する
2. F#を使って自分のコードを対話的にテストする
3. F#を使ってWebサービスを対話的に操作する
4. F#を使ってUIを対話的に操作する

パート2 - 開発およびDevOpsスクリプトにF#を使う

5. ビルドとCIスクリプトにFAKEを使う
6. Webサイトの応答をチェックするF#スクリプト
7. RSSフィードをCSVに変換するF#スクリプト
8. WMIを使ってプロセスの統計をチェックするF#スクリプト
9. クラウドの設定と管理にF#を使う

パート3 - テストにF#を使う

10. 読みやすい名前の単体テストをF#で書く
11. F#を使って単体テストをプログラムで実行する
12. F#を使って他の方法で単体テストを書くことを学ぶ
13. FsCheckを使ってより良い単体テストを書く
14. FsCheckを使ってランダムなダミーデータを作成する
15. F#を使ってモックを作成する
16. F#を使って自動化されたブラウザテストを行う
17. 振る舞い駆動開発にF#を使う

パート4. データベース関連のタスクにF#を使う

18. F#を使ってLINQpadを置き換える
19. F#を使ってストアドプロシージャの単体テストを行う
20. FsCheckを使ってランダムなデータベースレコードを生成する
21. F#を使って簡単なETLを行う
22. F#を使ってSQL Agentスクリプトを生成する

パート5: F#を使うその他の興味深い方法

23. パーシングにF#を使う
24. ダイアグラムと可視化にF#を使う
25. WebベースのデータストアへのアクセスにF#を使う
26. データサイエンスと機械学習にF#を使う
(ボーナス)27: イギリスの発電所群の発電スケジュールをバランスさせる


パート5: コアの外でF#を使うその他の方法

この最後のグループの提案は、申し訳ありませんが、少し雑多なものです。 これらは主に分析とデータ処理にF#を使うことに関するもので、前回の投稿には収まらなかったものです。

23. パーシングにF#を使う

日常的な開発の過程で、何かをパースする必要がある場面は驚くほど多いです:文字列をスペースで分割する、CSVファイルを読み込む、 テンプレートで置換を行う、Webクローラー用にHTMLリンクを見つける、URIのクエリ文字列をパースするなど。

F#はML由来の言語であり、簡単な正規表現から本格的なパーサーまで、あらゆる種類のパーシングタスクに理想的です。

もちろん、一般的なタスクには多くの既製ライブラリがありますが、時には独自のものを書く必要があります。 良い例は、先ほど見たBDDフレームワークのTickSpecです。

TickSpecは、Given/When/Thenのいわゆる「Gherkin」形式をパースする必要があります。別のライブラリに依存するよりも、 Philにとっては、数百行で独自のパーサーを書く方が簡単(そして楽しい)だったのではないかと想像します。 ソースコードの一部はこちらで見ることができます。

独自のパーサーを書く価値があるもう一つの状況は、ひどいXML設定形式を持つ複雑なシステム(ルールエンジンなど)がある場合です。 設定を手動で編集する代わりに、非常に単純なドメイン固有言語(DSL)を作成し、それをパースして複雑なXMLに変換することができます。

Martin FowlerはDSLに関する彼の本で、 この例を挙げています。ステートマシンを作成するためにパースされるDSLです。 そして、こちらがそのDSLのF#実装です。

より複雑なパーシングタスクには、FParsecの使用を強くお勧めします。これはこの種のことに完璧に適しています。 たとえば、以下のパーシングに使われています: FogCreekの検索クエリCSVファイルチェス表記負荷テストシナリオ用のカスタムDSL

24. ダイアグラムと可視化にF#を使う

何かをパースまたは分析した後、データでいっぱいの表よりも、結果を視覚的に表示できると常に良いです。

たとえば、以前の投稿で、GraphVizと組み合わせてF#を使い、 依存関係のダイアグラムを作成しました。以下にサンプルを示します:

ダイアグラム自体を生成するコードは短く、約60行だけでした。 こちらで見ることができます。

GraphVizの代替として、FSGraphの使用も検討できます。

より数学的またはデータ中心の可視化には、いくつかの優れたライブラリがあります:

そして最後に、800ポンドのゴリラ - Excelがあります。

利用可能であれば、Excelの組み込み機能を使うのは素晴らしいです。そしてF#スクリプティングはExcelとうまく連携します。

Excelでチャートを作成したり、 Excelで関数をプロットしたりできます。さらにパワフルな統合のために、 FCellExcel-DNAプロジェクトがあります。

25. WebベースのデータストアへのアクセスにF#を使う

Web上には、引き出して愛されるのを待っている多くの公開データがあります。 型プロバイダーの魔法により、F#はこれらのWeb規模のデータストアをワークフローに直接統合するのに適しています。

ここでは、FreebaseとWorld Bankという2つのデータストアを見ていきます。 近々さらに多くのものが利用可能になる予定です - 最新情報はfsharp.orgのデータアクセスページを参照してください。

Freebase

このセクションのコードはgithubで入手可能です。

Freebase)は、多くのソースから収集された構造化データの大規模な協力型知識ベースとオンラインコレクションです。

始めるには、これまで見てきたように型プロバイダーのDLLをリンクするだけです。

このサイトはスロットル制限があるため、頻繁に使う場合はAPIキーが必要になるでしょう (APIの詳細はこちら

// 現在のディレクトリをスクリプトディレクトリと同じに設定
System.IO.Directory.SetCurrentDirectory (__SOURCE_DIRECTORY__)

// スクリプトディレクトリ下にFSharp.Dataが必要
//    nuget install FSharp.Data -o Packages -ExcludeVersion  
#r @"Packages\FSharp.Data\lib\net40\FSharp.Data.dll"
open FSharp.Data

// キーなし
let data = FreebaseData.GetDataContext()

// キーあり
(*
[<Literal>]
let FreebaseApiKey = "<ここにfreebase対応のgoogle APIキーを入力>"
type FreebaseDataWithKey = FreebaseDataProvider<Key=FreebaseApiKey>
let data = FreebaseDataWithKey.GetDataContext()
*)

型プロバイダーがロードされたら、次のような質問を始めることができます...

「アメリカの大統領は誰?」

data.Society.Government.``US Presidents``
|> Seq.map (fun p ->  p.``President number`` |> Seq.head, p.Name)
|> Seq.sortBy fst
|> Seq.iter (fun (n,name) -> printfn "%sは%i番目でした" name n )

結果:

George Washingtonは1番目でした
John Adamsは2番目でした
Thomas Jeffersonは3番目でした
James Madisonは4番目でした
James Monroeは5番目でした
John Quincy Adamsは6番目でした
...
Ronald Reaganは40番目でした
George H. W. Bushは41番目でした
Bill Clintonは42番目でした
George W. Bushは43番目でした
Barack Obamaは44番目でした

たった4行のコードでこれだけできるのは悪くありません!

では、「カサブランカはどんな賞を受賞した?」はどうでしょうか?

data.``Arts and Entertainment``.Film.Films.IndividualsAZ.C.Casablanca.``Awards Won``
|> Seq.map (fun award -> award.Year, award.``Award category``.Name)
|> Seq.sortBy fst
|> Seq.iter (fun (year,name) -> printfn "%s -- %s" year name)

結果は:

1943 -- Academy Award for Best Director
1943 -- Academy Award for Best Picture
1943 -- Academy Award for Best Screenplay

以上がFreebaseです。役立つものもあれば些細なものもある、たくさんの良い情報があります。

Freebase型プロバイダーの使い方の詳細

Freebaseを使って現実的なテストデータを生成する

FsCheckを使ってテストデータを生成する方法を見てきました。 同様に、Freebaseからデータを取得することで、より現実的なデータを得ることができます。

Kit Easonツイートでこの方法を示しました。 以下は彼のコードに基づく例です:

let randomElement =
    let random = new System.Random()
    fun (arr:string array) -> arr.[random.Next(arr.Length)]

let surnames = 
    FreebaseData.GetDataContext().Society.People.``Family names``
    |> Seq.truncate 1000
    |> Seq.map (fun name -> name.Name)
    |> Array.ofSeq

let firstnames = 
    FreebaseData.GetDataContext().Society.Celebrities.Celebrities
    |> Seq.truncate 1000
    |> Seq.map (fun celeb -> celeb.Name.Split([|' '|]).[0])
    |> Array.ofSeq

// 10人のランダムな人物を生成して表示
type Person = {Forename:string; Surname:string}
Seq.init 10 ( fun _ -> 
    {Forename = (randomElement firstnames); 
     Surname = (randomElement surnames) }
     )
|> Seq.iter (printfn "%A")

結果は:

{Forename = "Kelly"; Surname = "Deasy";}
{Forename = "Bam"; Surname = "Br?z?";}
{Forename = "Claire"; Surname = "Sludden";}
{Forename = "Kenneth"; Surname = "Kl?tz";}
{Forename = "?tienne"; Surname = "Defendi";}
{Forename = "Billy"; Surname = "Paleti";}
{Forename = "Alix"; Surname = "Nuin";}
{Forename = "Katherine"; Surname = "Desporte";}
{Forename = "Jasmine";  Surname = "Belousov";}
{Forename = "Josh";  Surname = "Kramarsic";}

世界銀行

このセクションのコードはgithubで入手可能です。

Freebaseとは対照的に、世界銀行オープンデータは、世界中の詳細な経済・社会情報を多く持っています。

セットアップはFreebaseと同じですが、APIキーは必要ありません。

// 現在のディレクトリをスクリプトディレクトリと同じに設定
System.IO.Directory.SetCurrentDirectory (__SOURCE_DIRECTORY__)

// スクリプトディレクトリ下にFSharp.Dataが必要
//    nuget install FSharp.Data -o Packages -ExcludeVersion  
#r @"Packages\FSharp.Data\lib\net40\FSharp.Data.dll"
open FSharp.Data

let data = WorldBankData.GetDataContext()

型プロバイダーをセットアップしたら、次のような本格的なクエリを実行できます:

「低所得国と高所得国の栄養失調率を比較するとどうなりますか?」

// 処理する国のリストを作成
let groups = 
 [| data.Countries.``Low income``
    data.Countries.``High income``
    |]

// 特定の年の指標からデータを取得
let getYearValue (year:int) (ind:Runtime.WorldBank.Indicator) =
    ind.Name,year,ind.Item year

// データを取得
[ for c in groups -> 
    c.Name,
    c.Indicators.``Malnutrition prevalence, weight for age (% of children under 5)`` |> getYearValue 2010
] 
// データを表示
|> Seq.iter (
    fun (group,(indName, indYear, indValue)) -> 
       printfn "%s -- %s %i %0.2f%% " group indName indYear indValue)

結果は:

Low income -- Malnutrition prevalence, weight for age (% of children under 5) 2010 23.19% 
High income -- Malnutrition prevalence, weight for age (% of children under 5) 2010 1.36%

同様に、以下は妊産婦死亡率を比較するコードです:

// 処理する国のリストを作成
let countries = 
 [| data.Countries.``European Union``
    data.Countries.``United Kingdom``
    data.Countries.``United States`` |]

// データを取得
[ for c in countries  -> 
    c.Name,
    c.Indicators.``Maternal mortality ratio (modeled estimate, per 100,000 live births)`` |> getYearValue 2010
] 
// データを表示
|> Seq.iter (
    fun (group,(indName, indYear, indValue)) -> 
       printfn "%s -- %s %i %0.1f" group indName indYear indValue)

結果は:

European Union -- Maternal mortality ratio (modeled estimate, per 100,000 live births) 2010 9.0 
United Kingdom -- Maternal mortality ratio (modeled estimate, per 100,000 live births) 2010 12.0 
United States -- Maternal mortality ratio (modeled estimate, per 100,000 live births) 2010 21.0

世界銀行型プロバイダーの使い方の詳細

26. データサイエンスと機械学習にF#を使う

これらの提案をすべて実践しているとします。FParsecでWebログを解析し、 SQL型プロバイダーで内部データベースから統計を抽出し、 Webサービスから外部データを取得しています。これらのデータを全て手に入れました - それで何ができるでしょうか?

最後に、データサイエンスと機械学習にF#を使うことについて簡単に見てみましょう。

これまで見てきたように、F#は探索的プログラミングに適しています - インテリセンス付きのREPLがあります。しかし、PythonやRとは異なり、 コードは型チェックされるので、2時間の処理ジョブの途中で例外によってコードが失敗することはありません!

PythonのPandasライブラリやRの'tseries'パッケージに馴染みがあれば、 Deedleを真剣に検討すべきです。これは使いやすく、高品質なデータおよび時系列操作用のパッケージです。 DeedleはREPLを使った探索的プログラミングに適していますが、効率的にコンパイルされた.NETコードでも使えます。

そして、Rをよく使う場合は、R型プロバイダー(もちろん)があります。 これは、RパッケージをあたかもNETライブラリであるかのように使えることを意味します。素晴らしいですね!

他にもF#フレンドリーなパッケージがたくさんあります。fsharp.orgでそれらについて知ることができます。


シリーズのまとめ

ふう!長い例のリストと多くのコードを見てきました。最後まで読んでいただいた方、おめでとうございます!

これによってF#の価値について新しい洞察が得られたことを願っています。 F#は単なる数学的または金融的な言語ではありません - 実用的な言語でもあります。 そして、開発、テスト、データ管理のワークフローにおけるあらゆる種類のことに役立ちます。

最後に、このシリーズを通じて強調してきたように、これらの使い方はすべて安全で、リスクが低く、段階的です。最悪の場合でも何が起こるでしょうか?

さあ、チームメイトや上司を説得してF#を試してみてください。そしてその結果を教えてください。

追記

この投稿の後、Simon Cousinsがツイートで1つ忘れているものがあると指摘しました - 追加せずにはいられません。

Simonの実世界でのF#の使用(発電用)について、彼のブログでもっと読むことができます。 fsharp.orgにはF#についてのさらなる証言があります。

results matching ""

    No results matching ""