おすすめ F# 本
なんか某所でまた F# が盛り上がっていますが,最近読んでいる F# 本が激しく良いのでご紹介.
Foundations of F# (Expert's Voice in .NET)
- 作者: Robert Pickering
- 出版社/メーカー: Apress
- 発売日: 2007/05/28
- メディア: ハードカバー
- クリック: 20回
- この商品を含むブログ (14件) を見る
何より素晴らしいのが,この手の技術書の中でも破格に読みやすい英語で書かれていることです.むしろ英語文章の教材にでもしたいぐらい.
おそらくこの本が一番向いているのは,.NET や C# をそこそこ知っている人が,関数型言語の入門書として最初に読んでみる,というケースでしょう.その用途だと『ふつうのHaskellプログラミング』よりもこっちの F# 本をおすすめします.
内容も豊富です.そして解説の順序がすばらしいので,分量が多いからといってそれほど苦にはなりません.細かい章立ては ここ で本文抜粋の PDF ファイルが公開されています.
CHAPTER 1 | Introduction |
CHAPTER 2 | How to Obtain, Install, and Use F# |
CHAPTER 3 | Functional Programming |
CHAPTER 4 | Imperative Programming |
CHAPTER 5 | Object-Oriented Programming |
CHAPTER 6 | Organizing, Annotating, and Quoting Code |
CHAPTER 7 | The F# Libraries |
CHAPTER 8 | User Interfaces |
CHAPTER 9 | Data Access |
CHAPTER 10 | Distributed Applications |
CHAPTER 11 | Language-Oriented Programming |
CHAPTER 12 | The F# Tool Suite and .NET Programming Tools |
CHAPTER 13 | Compatibility and Advanced Interoperation |
だいたい5章ぐらいまでで文法の基礎紹介がテンポ良く続き,第6章でメタプログラミングの顔見せ,第7章でライブラリの解説と続きます.その後は興味のあるところをつまみ食いしていくとよさげ.WinForms や,WPF,WCF,LINQ との連携についても触れられています.
個人的には第11章がツボで,Quoting を使ったメタプログラミング (C# 3.0 の Expression Tree 生成機能のように,F# の式も Quote によって木構造をもったデータに変換できます) なんていう話が登場します.他にも簡易計算言語を作るために,文法から Parser を自動生成し,DynamicMethod を使って IL を出力したりという話も.
後は12章がツールの紹介,13章が相互運用で,たとえば F# で定義した Union を C# からどうやって使うかといった話が続きます.
とりあえず第1章がサンプルとして公開 されていますので,これだけ読んでみるというのもありでしょう.
また,微妙にそこそこ日本でも売れているのか Amazon.co.jp にはまだ在庫があるようです.いまボタンを押せば 2 名様限定ですぐに手に入る模様.
本の購入者向けの追加サービスとして $10 で PDF 版が販売されているので,読了後もプログラミング時のオンラインヘルプ代わりに使えます.
http://www.apress.com/promo/tendollars/
とまあこれから F# を始めようという人には是非おすすめの一冊でした.てかこれ,日本語訳に向けてあちこち動いてみてもいい本ですな.
裏 CEDEC 2007
http://t-pot.tea-nifty.com/blog/2007/07/cedec_2007_4e9f.html
1 日目ですかー
担当セッションは 2 日目なので,無理するとやばそうなんですが,前日寝だめしておくと大丈夫だったりしないかなぁ?
avoid or solve?
C# 3.0 と let キーワード
そういえば C# 3.0 にも let キーワードがあったなぁと思いだし let 書きたくなる病.
FizzBuzz
例えば id:siokoshou:20070714:p1 で書いた FizzBuzz で無理矢理 let を使ってみる.
var f1 = Enumerable.Range(1, 100).Select( n => { if (0 == n % 15) return "FizzBuzz"; if (0 == n % 5) return "Buzz"; if (0 == n % 3) return "Fizz"; return n.ToString(); }); var f2 = from x in Enumerable.Range(1, 100) let a = x % 3 == 0 ? "Fizz" : "" let b = x % 5 == 0 ? "Buzz" : "" let c = (x % 3 != 0 && x % 5 != 0) ? x.ToString() : "" select a + b + c; var check = Enumerable.SequenceEqual(f1, f2); Console.WriteLine("f1 == f2 : {0}", check);
まあこれぐらいだとあんまり意味なさげ.
今年の1月1日から12月31日までを列挙
let が欲しくなるのは例えばこういうクエリかな.
var cal = from month in Enumerable.Range(1, 12) let year = DateTime.Today.Year let numDays = DateTime.DaysInMonth(year, month) from day in Enumerable.Range(1, numDays) select new DateTime(year, month, day);
2000年から2009年までの13日の金曜日は?
ちょっとそれらしい問題にしてみました.
var ft13 = from year in Enumerable.Range(2000, 10) let daysInThisYear = from month in Enumerable.Range(1, 12) let numDays = DateTime.DaysInMonth(year, month) from day in Enumerable.Range(1, numDays) select new DateTime(year, month, day) from date in daysInThisYear where date.Day == 13 && date.DayOfWeek == DayOfWeek.Friday select date; foreach (var item in ft13) { Console.WriteLine("{0}/{1}/{2}", item.Year, item.Month, item.Day); }
まあひとつきの日数が13より少ないことはないので,いったん日にちまで列挙するのは余計なんですが,それがまたわざとらしい.
2000/10/13
2001/4/13
2001/7/13
2002/9/13
2002/12/13
2003/6/13
2004/2/13
2004/8/13
2005/5/13
2006/1/13
2006/10/13
2007/4/13
2007/7/13
2008/6/13
2009/2/13
2009/3/13
2009/11/13
2000年から2009年までの各年の日曜日の数
無理矢理ひとつのクエリで書いてみました.
var mysundays = from year in Enumerable.Range(2000, 10) let daysInThisYear = from month in Enumerable.Range(1, 12) let numDays = DateTime.DaysInMonth(year, month) from day in Enumerable.Range(1, numDays) select new DateTime(year, month, day) let sundaysInThisYear = from date in daysInThisYear where date.DayOfWeek == DayOfWeek.Sunday select date select new { Year = year, SundayCount = sundaysInThisYear.Count() }; foreach (var item in mysundays) { Console.WriteLine("{0} => {1}", item.Year, item.SundayCount ); }
んー,さすがにこれぐらいになると関数定義してもよさげ.
Func<int, IEnumerable<DateTime>> daysInYear = year => from month in Enumerable.Range(1, 12) let numDays = DateTime.DaysInMonth(year, month) from day in Enumerable.Range(1, numDays) select new DateTime(year, month, day); var mysundays = from year in Enumerable.Range(2000, 10) let sundays = from date in daysInYear(year) where date.DayOfWeek == DayOfWeek.Sunday select date select new { Year = year, SundayCount = sundays.Count() }; foreach (var item in mysundays) { Console.WriteLine("{0} => {1}", item.Year, item.SundayCount ); }
2000 => 53
2001 => 52
2002 => 52
2003 => 52
2004 => 52
2005 => 52
2006 => 53
2007 => 52
2008 => 52
2009 => 52