Real World Haskell

―実戦で学ぶ関数型言語プログラミング

[cover photo]
TOPICS
Programming
発行年月日
PRINT LENGTH
720
ISBN
978-4-87311-423-1
原書
Real World Haskell
FORMAT
PDF
Ebook
4,180円
Ebookを購入する

関数型言語Haskellの実用的な書籍を作るプロジェクトから生まれた、「使える」Haskellプログラミングに重点を置いた実用書。Haskellを使って実際に何ができるのか、の視点から、多岐にわたるトピックを扱っています。型やモナドをはじめHaskell特有の言語仕様など基本的事項を押さえつつ、データベース、GUIプログラミング、システムプログラミング、バイナリフォーマットの解析、バーコード認識、並列プログラミング、ウェブアプリケーションの作成まで幅広い範囲をカバー。Haskellの可能性を拡げ限界に挑戦する、意欲的な一冊です。

目次

目次
まえがき

1章 始めましょう
  1.1 Haskellの環境
  1.2 インタプリタghciで始めましょう
  1.3 基本的対話:ghciを電卓として使う
  1.4 ghciでのコマンドラインの編集
  1.5 リスト
  1.6 文字列と文字
  1.7 型:最初の一歩
  1.8 簡単なプログラム

2章 型と関数
  2.1 なぜ型に気を配るのか
  2.2 Haskellの型システム
  2.3 型システムに期待できること
  2.4 基本の型
  2.5 関数適用
  2.6 便利な合成データ型:リストとタプル
  2.7 リスト上の関数とタプル上の関数
  2.8 関数の型と純粋性
  2.9 Haskellのソースファイルと簡単な関数を書く
  2.10 例で評価を理解する
  2.11 Haskellにおける多相性
  2.12 2つ以上の引数を持つ関数の型
  2.13 なぜ純粋性にこだわるのか
  2.14 まとめ

3章 型を定義し、関数を単純化する
  3.1 新しいデータ型を定義する
  3.2 型シノニム
  3.3 代数データ型
  3.4 パターンマッチ
  3.5 レコード構文
  3.6 パラメータ化された型
  3.7 再帰型
  3.8 エラー報告表示
  3.9 局所変数の導入
  3.10 式のオフサイドルールおよび白空白
  3.11 case式
  3.12 パターンに関する初心者に共通する間違い
  3.13 ガード条件節の評価

4章 関数プログラミング
  4.1 Haskellで考える
  4.2 簡単なコマンドラインフレームワーク
  4.3 準備体操:可搬性のあるテキスト行分割
  4.4 中置関数
  4.5 リストを使う
  4.6 ループをどのように考えるか
  4.7 無名(ラムダ)関数
  4.8 部分関数適用とカリー化
  4.9 アズパターン
  4.10 合成によるコードの再利用
  4.11 読みやすいコードを書くコツ
  4.12 スペースリークと正格評価

5章 ライブラリを書く:JSONデータの操作
  5.1 JSONひとまわり
  5.2 HaskellにおけるJSONデータ表現
  5.3 Haskellモジュールの構造
  5.4 Haskellソースをコンパイルする
  5.5 Haskellプログラムの生成およびモジュールのインポート
  5.6 JSONデータを印字する
  5.7 型推論は両刃の剣
  5.8 表示可能形式への変換のさらなる一般化を考える
  5.9 混乱せずにHaskellコードを開発する
  5.10 文字列をプリティプリントする
  5.11 配列、オブジェクト、モジュールヘッダ
  5.12 モジュールヘッダを書く
  5.13 プリティプリンタライブラリに肉付けする
  5.14 パッケージを作る
  5.15 実用的指針および次に読むべきもの

6章 型クラスを使う
  6.1 型クラスの必要性
  6.2 型クラスとは何か
  6.3 型クラスのインスタンスを宣言する
  6.4 重要な組み込み型クラス
  6.5 自動導出
  6.6 型クラスの実際:JSONをもっと簡単に使う
  6.7 開かれた世界に生きていること
  6.8 既存の型に新しいアイデンティティを与える方法
  6.9 重複インスタンスのないJSON型クラス
  6.10 手ごわい単相性制限
  6.11 まとめ

7章 入出力
  7.1 Haskellにおける古典的入出力
  7.2 ファイルおよびハンドルを使う
  7.3 規模の大きい例:関数的入出力と一時ファイル
  7.4 遅延入出力
  7.5 IOモナド
  7.6 Haskellは本当は命令的なのか
  7.7 遅延入出力に伴う副作用
  7.8 バッファリング
  7.9 コマンドライン引数を読む
  7.10 環境変数

8章 効率的なファイル処理、正規表現、ファイル名マッチング
  8.1 効率的なファイル処理
  8.2 ファイル名マッチング
  8.3 Haskellにおける正規表現
  8.4 もっと正規表現
  8.5 グロブパターンを正規表現に翻訳する
  8.6 大事な話: 遅延関数を書く
  8.7 作成したパターン照合器を使う
  8.8 APIの設計を通じてエラー処理をする
  8.9 上手く動くコードにしよう

9章 入出力事例研究:ファイルシステム検索ライブラリ
  9.1 findコマンド
  9.2 簡単なところから始める:ディレクトリの再帰的リストアップ
  9.3 素朴な検索関数
  9.4 述語:純粋性を保ちつつ、貧弱な機能から充実した機能へ
  9.5 ファイルサイズを安全に決める
  9.6 述語用の特定問題領域言語(DSL)
  9.7 走査方法の制御
  9.8 密度、可読性、学習プロセス
  9.9 走査の別の見方
  9.10 役立つコーディングガイドライン

10章 コード事例研究: バイナリデータフォーマットの構文解析
  10.1 グレースケールファイル
  10.2 生PGMファイルの構文解析
  10.3 「ボイラープレート」コードの除去
  10.4 暗黙の状態
  10.5 ファンクタを導入する
  10.6 Parseに対するFunctorインスタンスを書く
  10.7 ファンクタを使って構文解析を行う
  10.8 PGM構文解析器を書き直す
  10.9 今後の方向性

11章 テストと品質保証
  11.1 QuickCheck:型に基づいたテスト
  11.2 テストの事例研究:プリティプリンタの仕様を作成する
  11.3 HPCを使ってテストカバレッジを測定する

12章 バーコード認識
  12.1 バーコードについて少し
  12.2 配列とは
  12.3 EAN-13バーコードのエンコード
  12.4 デコーダの制約
  12.5 分割統治
  12.6 カラー画像を扱いやすくする
  12.7 画像に何をしたのか
  12.8 適合する数字を探す
  12.9 配列もハッシュテーブルもない生活
  12.10 数字の混沌から答えを出す
  12.11 行データを扱う
  12.12 全部一緒に引っぱり上げる
  12.13 開発スタイルについてのコメント

13章 データ構造
  13.1 連想リスト
  13.2 マップ
  13.3 関数もデータ
  13.4 規模の大きい例:/etc/passwd
  13.5 規模の大きい例:数値型
  13.6 データとしての関数を利用する
  13.7 汎用シーケンス

14章 モナド
  14.1 前に書いたコードを復習する
  14.2 共有パターンを探す
  14.3 Monad型クラス
  14.4 ここで専門用語を少し
  14.5 新しいモナドを使う:作品を見せてください
  14.6 純粋なコードとモナドのコードを混ぜる
  14.7 誤解を正す
  14.8 Loggerモナドを構築する
  14.9 Maybeモナド
  14.10 リストモナド
  14.11 doブロックを展開する
  14.12 Stateモナド
  14.13 モナドとファンクタ
  14.14 モナド則およびよいコーディングスタイル

15章 モナドを使ったプログラミング
  15.1 ゴルフの練習:連想リスト
  15.2 一般化された持ち上げ
  15.3 代替を探す
  15.4 配管を隠す遊び
  15.5 インタフェースを実装から分離する
  15.6 Readerモナド
  15.7 再び自動導出について
  15.8 IOモナドを隠蔽する

16章 Parsecを使う
  16.1 Parsec最初の一歩:単純なCSVの構文解析
  16.2 sepByコンビネータとendByコンビネータ
  16.3 選択およびエラー
  16.4 規模の大きい例:完全なCSV解析器
  16.5 ParsecとMonadPlus
  16.6 URLエンコードしたクエリストリングの解析
  16.7 ちょっとした解析でも正規表現は不要
  16.8 変数なしでの解析
  16.9 構文解析のための作用ファンクタ
  16.10 作用型解析:例
  16.11 JSONデータの解析
  16.12 HTTPリクエストの解析

17章 Cとのインタフェース: FFI
  17.1 外部言語バインディング: 基礎
  17.2 Haskell用正規表現: PCREへのバインディング
  17.3 HaskellとCとの間で文字列データを受け渡す
  17.4 文字列との照合

18章 モナド変換子
  18.1 動機:ボイラープレートの回避
  18.2 単純なモナド変換子の例
  18.3 モナドおよびモナド変換子における共通のパターン
  18.4 複数のモナド変換子を積み上げる
  18.5 積んだところを下へ降りる
  18.6 作って理解するモナド変換子
  18.7 変換子の積み重ね順は重要
  18.8 モナドとモナド変換子を視野に入れる

19章 エラー処理
  19.1 データ型を使ったエラー処理
  19.2 例外
  19.3 モナド内でのエラー処理

20章 Haskellのシステムプログラミング
  20.1 外部プログラムを走らせる
  20.2 ディレクトリ情報とファイル情報
  20.3 プログラムの終了
  20.4 日付と時間
  20.5 規模の大きい例:パイプ

21章 データベースを使う
  21.1 HDBCの概要
  21.2 HDBCとドライバをインストールする
  21.3 データベースへの接続
  21.4 トランザクション
  21.5 単純なクエリ
  21.6 SqlValue
  21.7 クエリパラメータ
  21.8 プリペアド文
  21.9 結果を読み出す
  21.10 データベースメタデータ
  21.11 エラー処理

22章 規模の大きい例:ウェブクライアントプログラミング
  22.1 基本となる型
  22.2 データベース
  22.3 構文解析器
  22.4 ダウンロード
  22.5 メインプログラム

23章 gtk2hsを使ったGUIプログラミング
  23.1 gtk2hsをインストールする
  23.2 GTK+階層の外観
  23.3 Gladeを使ったユーザインタフェースの設計
  23.4 イベント駆動プログラミング
  23.5 GUIの初期化
  23.6 「Add Podcast」ウィンドウ
  23.7 長くかかるタスク
  23.8 Cabalを使う

24章 並行マルチコアプログラミング
  24.1 並行と並列を定義する
  24.2 スレッドを使った並行プログラミング
  24.3 単純なスレッド間通信
  24.4 メインスレッドと他のスレッドの待ち合わせ
  24.5 チャネルを通じた通信
  24.6 知っておくと便利なこと
  24.7 状態を共有する並行性はやはり難しい
  24.8 GHCでマルチコアを使う
  24.9 Haskellの並列プログラミング
  24.10 並列戦略とMapReduce

25章 プロファイリングと最適化
  25.1 Haskellプログラムのプロファイルを取る
  25.2 評価を制御する
  25.3 Core言語を理解する
  25.4 先進的技法:融合

26章 高度なライブラリの設計:ブルームフィルタ
  26.1 ブルームフィルタの紹介
  26.2 ユースケースとパッケージレイアウト
  26.3 基本設計
  26.4 STモナド
  26.5 修飾付きインポートのためのAPIを設計する
  26.6 可変ブルームフィルタを作成する
  26.7 非変更API
  26.8 使いやすいインタフェースを作成する
  26.9 Cabalパッケージを作る
  26.10 QuickCheckを使ってテストする
  26.11 性能分析とチューニング

27章 ソケットとsyslog
  27.1 基本のネットワーキング
  27.2 UDPによる通信
  27.3 TCPによる通信

28章 ソフトウェア・トランザクショナル・メモリ
  28.1 基本的な考え方
  28.2 いくつかの単純な例
  28.3 STMと安全性
  28.4 トランザクションの再試行
  28.5 選択肢から選ぶ
  28.6 I/OとSTM
  28.7 スレッド間の通信
  28.8 並行動作するWebリンクチェッカ
  28.9 STMの実践的側面

付録A GHCとHaskellライブラリをインストールする
  A.1 GHCのインストール
  A.2 Haskellソフトウェアをインストールする

付録B 文字、文字列、エスケープ規則
  B.1 文字および文字列リテラルを書く
  B.2 国際的言語サポート
  B.3 テキストをエスケープする

索引