書籍概要

実践F# 関数型プログラミング入門

著者
発売日
更新日

概要

.NETで使われているジェネリックやラムダ式は,関数型言語では早くから提供されていた機能であり,.NET向けに実装されたものといえます。関数型言語は、古くから存在するにも関わらず,手続型言語になれたユーザには難しいものと敬遠されてきました。昨今のクラウド化/マルチコアが現実的になり,いよいよ関数型が必要になってきました。本書はF#のプログラミング解説に留まらず,関数型がどのようなものか理解でき,技術者が興味のある「実際に関数型言語をどのようにシステムに組み込むべきか」というところまで解説しています。

こんな方におすすめ

  • 関数型言語に興味を持っている方
  • F#に興味がある方

目次

1章 関数型言語の潮流

  • 1.1 プログラミング言語の歴史
  • 1.2 プログラミング言語の分類
  • 1.3 プログラミングパラダイム
  • 1.4 プログラミング言語と抽象化の関係
  • 1.5 不遇の関数型言語
  • 1.6 並列コンピューティングへの流れ
  • 1.7 並列コンピューティングに適したパラダイム

2章 F#の基本

  • 2.1 F#とは
  • 2.2 F#の導入
  • 2.3 F#の基本的な使用方法
  • 2.4 おまけ(リファレンス)

第3章 F#へようこそ

  • 3.1 Hello, F# Interactive!
  • 3.2 高級な電卓
  • 3.3 コメント
  • 3.4 itの正体
  • 3.5 変数束縛
  • 3.6 初めての関数
  • 3.7 ローカル変数
  • 3.8 式と文
  • 3.9 ファーストクラス関数
  • 3.10 束縛≠代入
  • 3.11 シャドウイング

第4章 土台を超えて

  • 4.1 等値比較と真偽値
  • 4.2 大小比較
  • 4.3 論理演算
  • 4.4 条件式
  • 4.5 連なった条件式
  • 4.6 ユニット-値がないことを示す
  • 4.7 ユニットと副作用
  • 4.8 可変な変数
  • 4.9 By Value
  • 4.10 タプル-複数の値を組にする
  • 4.11 カリー化
  • 4.12 演算子
  • 4.13 ビット単位演算子
  • 4.14 パイプライン演算子
  • 4.15 高階関数
  • 4.16 関数合成演算子
  • 4.17 再帰
  • 4.18 末尾再帰
  • 4.19 相互再帰

第5章 強い静的型付け

  • 5.1 コンパイルタイム
  • 5.2 インライン関数
  • 5.3 プリミティブ型
  • 5.4 型変換
  • 5.5 算術オーバーフロー/モジュールの使用
  • 5.6 nanとinfinity/名前空間とオブジェクトの使用
  • 5.7 printfのふしぎ
  • 5.8 型推論
  • 5.9 演算子の特殊性
  • 5.10 パターンマッチ
  • 5.11 パターンの網羅性
  • 5.12 function式
  • 5.13 ユーザー定義型
  • 5.14 レコード
  • 5.15 判別共用体
  • 5.16 パターンマッチと識別子
  • 5.17 構造的な値
  • 5.18 型略称
  • 5.19 オプション
  • 5.20 ジェネリック-多相性
  • 5.22 型と制約と比較
  • 5.23 単位系
  • 5.24 ボクシング
  • 5.25 例外を発生させる
  • 5.26 例外の捕捉

第6章 不純の価値は

  • 6.1 冗語構文から軽量構文へ
  • 6.2 モジュール
  • 6.3 アクセス制御
  • 6.4 命令型のループ
  • 6.5 参照セル
  • 6.6 値制限
  • 6.7 クロージャ
  • 6.8 リファレンス スコープの封鎖
  • 6.9 副作用と参照透明性
  • 6.10 関数アウトサイダー
  • 6.11 参照渡し
  • 6.12 出力のための引数
  • 6.13 評価戦略
  • 6.14 遅延実行
  • 6.15 選ばれなかった式
  • 6.16 標準入出力
  • 6.17 リソース

第7章 コレクション!コレクション!コレクション!

  • 7.1 リスト
  • 7.2 再帰型
  • 7.3 また再帰
  • 7.4 またまた再帰
  • 7.5 制約を逃れる
  • 7.6 リストの結合
  • 7.7 内包的記法
  • 7.8 リスト操作ひとめぐり
  • 7.9 配列
  • 7.10 多次元配列
  • 7.11 配列のインデックス
  • 7.12 シーケンス
  • 7.13 シーケンスに親しむ
  • 7.14 レガシーとの協調
  • 7.15 unfold
  • 7.16 遅延の終わり
  • 7.17 遅延コストを払うのは誰だ
  • 7.18 参照型
  • 7.19 集合
  • 7.20 辞書

第8章 OOP Mix

  • 8.1 F#とオブジェクト指向プログラミング
  • 8.2 本当は全部がオブジェクト
  • 8.3 クラス
  • 8.4 素朴なクラス
  • 8.5 パイプラインとともに
  • 8.6 名前付き引数とオプショナル引数
  • 8.7 オーバーロード
  • 8.8 抽象クラス
  • 8.9 継承のうれしさ
  • 8.10 キャスト
  • 8.11 インターフェース
  • 8.12 nullの是非を問う
  • 8.13 後始末
  • 8.14 オブジェクト式
  • 8.15 アクティブパターン
  • 8.16 構造体
  • 8.17 デリゲート
  • 8.18 列挙型
  • 8.19 型拡張
  • 8.20 演算子オーバーロード
  • 8.21 ジェネリック制約

第9章 .NET Frameworkのライブラリを使用する

  • 9.1 F#から見た.NET Framework
  • 9.2 オブジェクトの持つメンバー呼び出しの基本
  • 9.3 標準入出力を使う
  • 9.4 ファイルの入出力を行う
  • 9.5 GUIを持つWindowsアプリケーションを作成する
  • 9.6 使用方法のまとめ

第10章 モジュールとシグネチャ

  • 10.1 モジュール
    • 10.1.1 関数の再利用
    • 10.1.2 関数の組み合わせ
    • 10.1.3 モジュール
    • 10.1.4 Visual Studioでモジュールを作成する
    • 10.1.5 名前空間
    • 10.1.6 共通言語ランタイムとモジュールの関係
  • 10.2 シグネチャ
    • 10.2.1 シグネチャとは
    • 10.2.2 シグネチャの詳細説明

第11章 ワークフローと非同期ワークフロー

  • 11.1 ワークフロー
    • 11.1.1 式という概念の全体像
    • 11.1.2 コンピュテーション式の全体像
    • 11.1.3 シーケンス式
    • 11.1.4 コンピュテーション式
    • 11.1.5 ワークフローを支える逐次実行とは
  • 11.2 非同期ワークフロー
    • 11.2.1 非同期ワークフローが必要な理由
    • 11.2.2 非同期ワークフローの仕組みについて
    • 11.2.3 非同期ワークフローの応用例
  • 11.3 メッセージと非同期ワークフロー
    • 11.3.1 メッセージの基本的な活用
    • 11.3.2 エージェントに停止機能を持たせるには
    • 11.3.3 エージェントから値を受け取るには
    • 11.3.4 メッセージを選択するエージェントを作成するには
    • 11.3.5 エージェントの応用例

第12章 F#を拡張するライブラリ

  • 12.1 ASP.NET Webアプリケーション
    • 12.1.1 Webフォームを作成する
  • 12.2 LINQの活用
  • 12.3 パラレルLINQの活用
  • 12.4 ユーティリティツール
    • 12.4.1 HTMLドキュメント生成ツール(fshtmldoc.exe)
    • 12.4.2 字句解析器と構文解析器
  • 12.5 その他のライブラリ
    • 12.5.1 FSharp.PowerPack.dll
    • 12.5.2 FSharp.PowerPack.Metadata.dll
    • 12.5.3 ライブラリの使い方を探すには

Appendix

  • A 本書の用語集
  • B 参考資料
  • C コード クオート式
  • D イベントについて

サポート

正誤表

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

P.21 1.1.1

MPU4040
Intel 4004

P.32 1.5.3

関数型専用コンピュータの存在から理解できるように
関数型専用コンピュータが関数型言語の実行を最適化したように

P.33 1.6.1

「トランジスタの集積度は2年毎に倍増する」
「トランジスタの複雑度は2年毎に倍増する」

P.*93 4.11

関数を評価値に得ることを
新たな関数を評価値として得ることを

P.102 4.15

float関数
floor関数

P.103 4.15

dticket
ticket

P.106 リスト4-62

areaOfCircle << round
round << areaOfCircle

P.115 5.2

インライン展開とはコンパイル時のβ変換であり、β変換とは関数定義による式の置き換えです。つまり以下のような変換を言います
インライン展開とは、コンパイル時に、関数呼び出しをその定義によって置き換えることを言い、簡単に示すと以下のようになります

P.115 5.2

β変換は、通常、実行時の関数適用によって行われます。
このような式の展開は、通常、実行時の関数適用によって行われます。

P.157 囲み

// OCaml 互換
type 'a 'b 'c ... 型名 = ...

// .NET Framework互換
type 型名<'T, 'U, 'V...> = ...
// OCaml 互換
type ('a, 'b, 'c ...) 型名 = ...

// .NET Framework 互換
type 型名<'T, 'U, 'V ...> = ...

P.159 リスト5-86

=> 0
=> 4

P.173 5.26.1

try ... with式のtry節にtry ... finally式をネスト
try ... finally式のtry節にtry ... with式をネスト

P.177 表6-1

MySttuct
MyStruct

P.183 6.4.3

fot ... in式は
for ... in式は

P.185 6.6

参照は多相性を持ちます
参照セルは多相性を持ちます

P.192 6.10

極端な話、普段は参照透明に使えるのに、ある特定の時刻にのみ特殊な結果を算出して参照透明にならない、などという
極端な話、普段は参照透明であるかのように使えるのに、ある特定の時刻にのみ特殊な結果を算出して参照透明性を崩す動作をする、などという

P.193 図6.4

&X
&x

P.201 Column

stdinとはTextReaderであり、stdoutとstderrとはTextWriterのことです。
stdinはConsole.In、stdoutはConsole.Out、stderrはConsole.Errorのことです。

P.207 7.1.1

値制限になってしまう
値制限のエラーになってしまう

P.211 リスト7-8

-     Node(7, Node(3, Node(1, Empty, Empty),
-     Node(8, Node(3, Node(1, Empty, Empty),

P.211 リスト7-8

  Node
    (7,
     Node
  Node
    (8,
     Node

P.214 7.4.1

なお、insertとinsertSortはどちらも末尾再帰ではない
なお、リスト7-13で示したinsertとinsertionSortは、どちらも末尾再帰でない

P.218 リスト7-21

// 2 番目の要素を 3 番目に
// 2 番目の要素を 0 番目に

P.221 7.8.2

max、min、average
max、min、sum、average

P.226 リスト7-40

([1..3], [10..30])
([1..3], [10..10..30])

P.229 7.8.15

exsits、forall
exists、forall

P.240 リスト7-65

> Seq.isEmpty emp, Seq.isEmpty sgl;;
> Seq.empty |> Seq.isEmpty, Seq.singleton "F#" |> Seq.isEmpty;;

P.250 リスト7-88

printfn "%d" n
printf "%d " n

P.273 8.6.1

見立てを変えたことで、引数はタプルではありませんから、パイプラインには流せません
見立てを変えたことによって、名前付きの引数はもはやタプルではありませんから、パイプラインに流すことはできません

P.291 リスト8-64

SEACRET
SECRET

P.299 リスト8-75

> type Foo =
> type MyClass =

P.317 9.2.1

意味しており、複数の引数は丸括弧で囲んだタプルにします
意味しています

P.322 9.3

printfn関数の書式指定子である%Aに相当し
printfn関数の書式指定子である%Oに相当し

P.347 リスト10-21

Printfn "getCharge 6 =%A" (Charge.getCharge 20)
Printfn "getCharge 20 =%A" (Charge.getCharge 20)

P.359 10.2.1

Libraray1という名前空間を宣言してModule1というモジュール宣言を使用している
Library1という名前空間を宣言してModule1というモジュール宣言を使用している

P.361 10.2.1

コンストラクターをプライベートに定義したと考えられますが
コンストラクターをインターナルに定義したと考えられますが

P.362 図10-7

プライベートメンバーになる
インターナルメンバーになる

P.371 11.1.3

遅延実行という特徴を実現するために、リストや配列というデータ型があるにも関わらず、
リストや配列というデータ型があるにも関わらず、遅延実行という特徴を実現するために

P.372 図11-1

Seq.append (printfn "First = %A " n, Seq.singleton n)
Seq.append (printfn "First = %A " n; Seq.empty) (Seq.singleton n)

P.372 図11-1

Seq.append (printfn "Second = %A " n, Seq.singleton n)
Seq.append (printfn "Second = %A " n; Seq.empty) (Seq.singleton n)

P.372 図11-1

Seq.append (printfn "Third = %A " n, Seq.singleton n)
Seq.append (printfn "Third = %A " n; Seq.empty) (Seq.singleton n)

P.373 図11-2

Seq.append (printfn "First = %A " n, Seq.singleton n)
Seq.append (printfn "First = %A " n; Seq.empty) (Seq.singleton n)

P.373 図11-2

Seq.append (printfn "Second = %A " n, Seq.singleton n)
Seq.append (printfn "Second = %A " n; Seq.empty) (Seq.singleton n)

P.373 図11-2

Seq.append (printfn "Third = %A " n, Seq.singleton n)
Seq.append (printfn "Third = %A " n; Seq.empty) (Seq.singleton n)

P.380 リスト11-13

Delay (<fun:myExp@57-1>)
val myExp : (unit -> int)

> myExp();; // もしくは、ownBuilder.run myExp でも良い
Return (16)
実行 (<fun:Return@11>)
val it : int = 16
Delay (<fun:myExp@30>)
val myExp : (unit -> int)

> myExp ();;
Bind (10 , <fun:myExp@32-1>)
Return (16)
実行 (<fun:Return@18>)
val it : int = 16

P.381 11.1.4

「10, fun y -> ...」という式が「(fun y -> ...) 10」という式へと評価
ownBuilder.Bind(10, fun y -> ...)」という式が「(fun y -> ...) 10」という式へと評価

P.381 11.1.4

ビルダークラスを使って与えた式を順番に実行できる計算式という
与えられた式をビルダークラスを使って順番に実行できる計算式という

P.392 11.2.2

リスト11-18やリスト11-19は、キャンセル要求が通知された時に
リスト11-19やリスト11-20は、リスト11-18でキャンセル要求が通知された時に

商品一覧