WEB+DB PRESS plusシリーズ[増補改訂]関数プログラミング実践入門
──簡潔で,正しいコードを書くために

書籍の概要

この本の概要

現場の方々に向け,関数プログラミングのエッセンスを厳選解説した入門書。関数型言語Haskellを用い,基本から,Java 8/C/C++/Python/JavaScript/Rubyをはじめ各種命令型言語との比較,オススメの開発/設計テクニック等を平易に解説。改訂版ではGlasgow Haskell Compiler 8ならびに新機構のStackage/stackへの全面対応,関数型言語由来の他言語の機能解説章(第8章)の新設(Swift/Go/Rust/C#等の例も紹介)をはじめ実践開発に役立つ解説を増強し,関数型言語でも命令型言語でも活かせる「使える基本」を凝縮しました。

こんな方におすすめ

  • 簡潔なコードを書きたい方
  • 安全でバグらせにくい,正しいコードの設計/実装に関心のある方々
  • JavaやC++などメジャーな命令型言語の新機能と関数型言語の関係に興味をお持ちの方々

本書の構成

本書では,各章は次のような構成となっています。

第0章 [入門]関数プログラミング ——「関数」の世界

第0章は導入です。関数プログラミングと,その実現のための関数型言語とはそれぞれ一体どういうものなのかを説明します。合わせて,関数プログラミング界隈の人とコミュニケーションが取れる程度の,基本的な概念や特徴,用語,歴史などを紹介します。いろいろな関数型言語やそれらで書かれたプロダクトの紹介なども含まれます。

第1章 [比較で見えてくる]関数プログラミング ——C/C++,Java,JavaScript,Ruby,Python,そしてHaskell

第1章では,同一の問題設定の元でメジャーな言語のいずれかとHaskellを比較することで,Haskell(あるいは同様の関数型言語)の持つ機能がプログラミングに与える効果を俯瞰します。この時点ではHaskellの文法を説明していませんが,比較対照が存在しHaskellコードの解説も適宜盛り込んでいるため,エッセンスを読み取るのには支障がないような解説となっています。本当にはじめてHaskellに触れる方は,一度第1章をスキップし,第2章から第5章を読んでから戻ってきても良いでしょう。

第2章 型と値 ——「型」は,すべての基本である

第3章 関数 ——関数適用,関数合成,関数定義,再帰関数,高階関数

第4章 評価戦略 ——遅延評価と積極評価

第5章 モナド ——文脈を持つ計算を扱うための仕掛け

第2章から第5章までは,Haskellをはじめ多くの関数型言語の安全性に多大な貢献を

果たす「型」,Haskellのコードを読み書きするための基本的な文法や,Haskellと他の言語で実際に計算が進んでいくしくみの違い,特徴的で他の命令型言語で取り入れられ始めた機能であるモナドなどについて詳解します。

第6章 オススメの開発/設計テクニック ——「関数型/Haskellっぽい」プログラムの設計/実装,考え方

第6章では,Haskellでのオススメの設計法を,その思考過程がわかるようにステップバイステップ(step by step)で説明していきます。何がHaskellらしいコードであり,どう考えればそのようなコードを書けるのか,その手段の一つを把握できるでしょう。もし,(想定読者ではありませんが)あなたに関数型言語の経験があるのであれば,第5章までをスキップし第6章から読み始めるのは良い選択です。

第7章 Haskellによるプロダクト開発への道 ——パッケージとの付き合い方

第7章は,実際にHaskellを使ってプロダクトを作るにあたり,どうコードベースやライブラリを管理していけば良いかを扱います。あなたのプログラムをオープンソースとして公開したり,業務でHaskellを使ったりする場合の参考となるでしょう。

第8章 各言語に見られる関数プログラミングの影響 ——Ruby,Python,Java,JavaScript,Go,Swift,Rust,C#,C++

第8章は,既存の,あるいは比較的新しい言語において,関数プログラミングに特徴的な各要素/機能がどのように取り込まれているかを見ていきます。それぞれの言語で関数プログラミングを行う上での助けとなり,また,その言語そのものに対する理解を深めるきっかけとなるでしょう。

Appendix

巻末付録です。関数型言語が使えるプログラミングコンテストサイトや,ステップアップのために押さえておきたい参考文献や参考情報を紹介しました。

増補改訂における,おもな変更点

増補改訂に伴い,おもに以下の内容の追加/更新を行いました。

本書内で使われるHaskellサンプルコード/処理系について,執筆時点最新版のGHC8に全面対応

第0章,第7章を中心に,Haskell開発環境構築とパッケージ管理において現在デファクトスタンダードになりつつある,Stackage/Stackを採用し,その利用のための解説を追加

  • 1.6節「文書をルール通りに生成する ——安全なDSL」を新規追加
    • 2.7節「よくある誤解 ——実行時型情報を利用したい」を新規追加
    • 4.3節「評価の制御 ——パフォーマンスチューニングのために」において,評価の制御に関する解説をGHC8による関連拡張と共に強化
    • 第8章「各言語に見られる関数プログラミングの影響 ——Ruby,Python,Java,JavaScript,Go,Swift,Rust,C#,C++」を新設

本書で必要となる前提知識

本書では,前提として,以下に関する知識等を必要とします。❶❷は比較や概念の対比という形で現れます。❸は,Haskellや他の言語のサンプルコードを実際に試してみるためには必要です。  また,必須ではありませんが,第8章では❹の知識もあると良いでしょう。

  • ❶メジャーな命令型言語に対する経験/知識
    • Java,C言語,C++,Ruby,Python,JavaScriptなど
    • Java 8,C++11まで触れていると良い
  • ❷構造化プログラミングやオブジェクト指向プログラミングの基本事項
    • GoF(Gang of Four)のデザインパターンなど
  • ❸Unix系OSやWindowsの基本操作(コマンドプロンプトや各言語の開発/実行環境)
  • ❹比較的新しい言語の知識(Go,Rust,Swiftなど)

本書に関するお知らせ

本書に関連する記事を公開しております。

この書籍に関連する記事があります!

[知っておきたい]関数プログラミングの基本 ――安全性,生産性の高さの理由(わけ)
関数プログラミング(functional programming)は,命令を並べて順次実行させるプログラミングとは異なり,関数の組み合わせと適用によるプログラミングです。

目次

本書について

本書の構成

増補改訂における,おもな変更点

本書で必要となる前提知識

謝辞

第0章 [入門]関数プログラミング ——「関数」の世界

0.1 関数プログラミング,その前に ——実用のプログラムで活かせる強みを知る

  • 関数プログラミングから得られる改善

0.2 関数とは何か? ——命令型言語における関数との違い

  • 関数プログラミングにおける関数
  • 副作用

0.3 関数プログミングとは何か? ——「プログラムとは関数である」という見方

  • プログラミングのパラダイム
    • 命令型プログラミングのパラダイム
    • オブジェクト指向プログラミングのパラダイム
    • 関数プログラミングのパラダイム ——プログラムとは「関数」である
  • 関数の持つモジュラリティ ——「プログラムを構成する部品」としての独立性

0.4 関数型言語とは? ——関数が第一級の対象である? 代入がない?

  • 関数型言語であるための条件
    • 関数のリテラルがある
    • 関数を実行時に生成できる
    • 関数を変数に入れて扱える
    • 関数を手続きや関数に引数として与えることができる
    • 関数を手続きや関数の結果として返すことができる
  • 関数型言語と命令型言語
    • 代入がないことから得られるもの

Column いろいろな関数型言語

0.5 関数型言語の特徴的な機能 ——型の有無,静的/動的,強弱

  • 型付きと型なし
  • 静的型付けと動的型付け
  • 純粋
  • 型検査
  • 強い型付けと弱い型付け
  • 型推論

Column 弱い型付けは何のため?

  • 依存型
  • 評価戦略
  • おもな関数型言語と命令型言語の機能一覧

0.6 なぜ今関数型言語なのか? ——抽象化,最適化,並行/並列化

  • 関数型言語の抽象化 ——数学的な抽象化とは?
  • 関数型言語の最適化
  • 関数型言語と並行/並列プログラミング
    • 並行/並列という概念とプログラミングの難しさ
    • 目的から考える並行/並列プログラミング
    • 並行プログラミングの難しさ ——競合状態,デッドロック
    • 並列プログラミングの一助 ——参照透過性の保証

Column 関数型言語と定理証明

0.7 関数型言語と関数プログラミングの関係 ——強力な成果を引き出すために

  • 関数プログラミングの導入 ——命令型でも活かせる技法
  • 関数型言語による関数プログラミングの導入

0.8 関数型言語の歴史 ——過去を知り,今後を探る

  • 関数型言語のこれまで
  • 関数型言語のこれから
    • 進化の方向
    • 普及可能性

0.9 関数型言語を採用するメリット ——宣言的であること,制約の充足のチェック,型と型検査,型推論

  • 宣言的であることのメリット
  • 制約の充足をチェックしてくれるメリット
  • 型と型検査があることのメリット
  • 型推論のメリット

0.10 本書で取り上げる関数型言語 ——Haskellの特徴,実装,環境構築

  • Haskellが持つ特徴的な機能

Column 世界で一番美しい? クイックソート?

  • Haskellの実装
  • Haskell環境の構築
    • 対話的インタープリタGHCiの基本的な使い方
    • コンパイラGHCの基本的な使い方

0.11 まとめ

Column 現在関数型言語が採用されている分野/プロダクト

第1章 [比較で見えてくる]関数プログラミング ——C/C++,Java,JavaScript,Ruby,Python,そしてHaskell

1.1 部品を組み合わせる ——合う部品のみ合わせられる力

  • 同じものから同じものへの変換を組み合わせる
  • 2次元の座標変換
  • C言語の場合 ——合わない部品
  • JavaScriptの場合 ——合うかもしれない部品を作り/合わせる力
    • 組み合わせやすさは部品化の大前提
    • さらなる部品化
  • Haskellの場合 ——合う部品を作り/合う部品のみ合わせる力

1.2 文脈をプログラミングする ——NULL considered harmful

  • NULLが示すもの
  • NULLの危険性
  • 値がないことを扱う方法
    • C++(boost::optional)の場合 ——強力過ぎる例外処理のボイラープレート
    • Javaの場合 ——ネストしていくメソッドチェイン
    • Haskellの場合 ——行間に処理を発生させることのできる力

1.3 正しい並列計算パターン ——計算パターンの変化と影響

  • C(OpenMP)の場合 ——アノテーションによる並列化
    • 要件追加に対応するための不用意な変更
    • 失敗の原因と正しい変更
  • Haskellの場合 ——危険な並列化の排除
    • 要件追加に対応する変更
    • 純粋であることによって守られたもの

Column それでも並列化は難しい

1.4 構造化データの取り扱い ——Visitorパターン

  • Java(Visitorパターン)の場合 ——肥大化と引き換えの柔軟性
  • Haskellの場合 ——型の定義/利用のしさすさ
    • コード量の差が生じる要因
    • 型を簡単に定義できる
    • パターンマッチがある

1.5 型に性質を持たせる ——文字列のエスケープ

  • HTMLの文字列エスケープ
  • Rubyの場合 ——性質の改変は利用者の権利
    • 「エスケープ済みである」という性質をクラスで保護/保証する
    • 保証を破れる言語機能の存在
  • Haskellの場合 ——性質の保証は提供者の義務
    • 「エスケープ済みである」という性質を型で保護/保証する
    • 保証した性質を破らせない
  • 「型システムが強力である」ことが意味するもの
    •  ——その場所場所で,適切な型付けの度合いを選択する余地がある

1.6 文書をルール通りに生成する ——安全なDSL

  • 構造を持つ文書とルール
  • プログラムから文書を生成する方法
  • Pythonの場合 ——Jinja2で生成してみる
  • Haskellの場合 ——言語内DSL
  • 文脈にまで性質を持たせる

1.7 まとめ

第2章 型と値 ——「型」は,すべての基本である

2.1 Prelude ——基本のモジュール

  • 基本のPreludeモジュール ——モジュールのimportの基本

2.2 値 ——操作の対象

  • 値の基本
  • リテラル ——値の表現,およびその方法
    • 数値リテラル
    • 文字リテラル
    • 文字列リテラル
    • ラムダ式 ——関数のリテラル
  • 値コンストラクタ ——Haskellの真偽値True/Falseは値コンストラクタ

2.3 変数 ——値の抽象化

  • 変数
  • 定数
  • 束縛

2.4 型 ——値の性質

  • 型の基本
  • 型の確認と型注釈
  • 関数の型
    • カリー化
  • 意図的に避けた型の確認
  • 型検査
  • 多相型と型変数
    • リスト
    • タプル
    • Either
    • Maybe
  • 型推論

2.5 型を定義する ——扱う性質の決定

  • 既存の型に別名を付ける ——type宣言
  • 既存の型をベースにした新しい型を作る ——newtype宣言
  • 完全に新しい型を作る ——代数データ型
    • 代数データ型の定義の基本 ——HTTPステータス
    • レコードを使う ——色空間RGBA
    • 多相型に定義し直してみる ——2次元の座標空間
    • 再帰型の定義 ——自然数
    • 多相型と再帰型 ——2分木
  • 代数データ型と直積/直和

2.6 型クラス ——型に共通した性質

  • 型クラスとは何か?
  • 型クラスを調べる
  • いろいろな型クラス
    • Show
    • Read
    • Num
    • Fractional
    • Floating
    • Integral
    • Eq
    • Ord
    • Enum
    • Bounded

2.7 よくある誤解 ——実行時型情報を利用したい

  • 型を見て分岐したい
  • 実行時型情報と型検査の相性

2.8 まとめ

Column コンストラクタ名に惑わされず,データの構造を捉える

第3章 関数 ——関数適用,関数合成,関数定義,再帰関数,高階関数

3.1 関数を作る ——既存の関数から作る,直接新たな関数の定義する

  • 関数を作る方法

3.2 関数適用 ——既存関数の引数に,値を与える

  • 関数適用のスペース
  • 関数適用の結合優先度
  • 関数の結果としての関数との関数適用
  • 関数の2項演算子化
  • 2項演算子の関数化
    • セクション
  • 部分適用

3.3 関数合成 ——既存の関数を繋げる

  • 関数合成と,合成関数

3.4 Haskellのソースファイル ——ソースファイルに関数を定義し,GHCi上でそれを読み込む

  • サンプルファイルの準備とGHCiへの読み込み
  • ソースファイルへの追加/編集,再読み込み

3.5 関数定義 ——パターンマッチとガード

  • 一般的な関数の定義
  • パターンマッチ ——データの構造を見る
    • 直接的な値にマッチさせる
    • コンストラクタにマッチさせる
    • 複合的なパターンマッチ
    • パターンマッチの網羅性
    • asパターン
    • プレースホルダ
  • ガード ——データの性質を見る
    • 網羅的でないガード条件
  • パターンマッチとガードを組み合わせる
  • caseとif

Column 「文」と「式」と,その判別

  • where/let

Column 場合分けの構文糖衣 ——実は,全部case

    • let式
    • where節

3.6 再帰関数 ——反復的な挙動を定義する関数

  • 3つの制御構造と,再帰関数の位置付け ——連結,分岐,反復
  • 再帰的定義
  • 関数の再帰的定義
  • いろいろな再帰関数
    • length
    • take/drop
    • 挿入ソート
  • 再帰的な考え方のコツ
  • 再帰の危険性とその対処

Column そんなに再帰して大丈夫か(!?)

3.7 高階関数 ——結果が関数になる関数,引数として関数を要求する関数

  • 高階関数とは?
  • 結果が関数になる関数
  • 引数として関数を要求する関数
  • 高階関数を定義する
  • いろいろな高階関数
    • filter
    • map
    • zip(zipWith)
    • foldl/foldr
    • scanl/scanr
    • 実際に使ってみる ——部分列の列挙

3.8 まとめ

第4章 評価戦略 ——遅延評価と積極評価

4.1 遅延評価を見てみよう ——有効利用した例から,しっかり学ぶ

  • たらい回し関数(竹内関数)
    • たらい回し関数の定義
    • たらい回し関数の実行——C++版
    • たらい回し関数の実行——Haskell版
    • たらい回しの省略
  • 無限のデータ
    • レンジによる無限列
    • 再帰的定義による無限列
    • フィボナッチ数列,再び
    • 無限に広がる2分木
  • 省略によるエラー耐性
    • 実行時のエラー
    • 最高の実行時エラー対策 ——それは,実行しないこと
  • 平均値
    • 通常の平均値の計算
    • ちょっと変わった平均値の計算

4.2 評価戦略 ——遅延評価と積極評価のしくみ,メリット/デメリット

  • 評価戦略と遅延評価
  • 簡約
    • 正規形
    • 簡約の順番
    • 順番による結果の違い
  • 積極評価
    • C言語
  • 遅延評価
    • 最左最外簡約
    • WHNF(弱冠頭正規形)
    • サンク
    • グラフ簡約
  • 積極評価と遅延評価の,利点と欠点
    • 積極評価の利点,遅延評価の欠点
    • 遅延評価の利点,積極評価の欠点

4.3 評価を制御する ——パフォーマンスチューニングのために

  • 評価の進む様子を観察する
  • サンクを潰す
    • コンストラクト時に潰す
    • 束縛時に潰す ——BangPatterns
    • モジュール単位で潰す ——積極評価のHaskell
    • サンクを潰したいケース ——スペースリークの恐怖
  • Haskell版たらい回し関数を遅くする
  • C++版たらい回し関数を速くする

4.4 まとめ

Column パフォーマンスチューニングの第一歩 ——プロファイルを取る

第5章 モナド ——文脈を持つ計算を扱うための仕掛け

5.1 型クラスをもう一度 ——自分で作るという視点で

  • 型クラスを定義する
  • 型クラスのインスタンスを作る
  • 型クラスインタフェースのデフォルト実装
  • [比較]他の言語の「あの機能」と「型クラス」
    • インタフェースの後付け
    • 同じ型であることの保証

5.2 モナドの使い方 ——文脈をうまく扱うための型クラスインタフェース

  • 文脈を持つ計算 ——モナドを使うモチベーション
    • どこかで失敗するかもしれない計算 ——Maybeモナド
    • 複数の結果を持つ計算 ——リストモナド
    • 同じ環境を参照する計算 ——((->) r)というモナド
  • 型クラスとしてのモナド ——アクション,return(注意!),bind演算子
  • モナド則 ——インスタンスが満たすべき,3つの性質
  • 「モナド則を満たしていないモナド型クラスのインスタンス」の例,
    • とHaskellでの注意点
  • do記法
    • do記法とモナド則

5.3 いろいろなモナド ——Identity,Maybe,リスト,Reader,Writer,State,IO ...

  • Identity ——文脈を持たない
  • Maybe ——失敗の可能性を持っている
    • 現実世界と理想的な型の世界の接続と失敗
  • リスト ——複数の可能性を持っている
    • リスト内包表記
    • 文脈の多相性
  • Reader ——参照できる環境を共有する
    • configを参照する処理
  • Writer ——主要な計算の横で,別の値も一直線に合成する
  • State ——状態の引き継ぎ
  • IO ——副作用を伴う
    • 副作用を扱えるのに純粋と言える理由

5.4 他の言語におけるモナド ——モナドや,それに類する機能のサポート状況

  • 他の関数型言語とモナド
  • 命令型言語とモナド ——Javaのモナドとの比較
    • Optionalクラス
    • Streamクラス
    • メソッドチェインの弊害 ——do記法のありがたみ
    • 副作用による汚染は防げない

5.5 Haskellプログラムのコンパイル ——コンパイルして,Hello, World!

  • 「普通」の実行方法について ——コンパイルして実行する

5.6 まとめ

Column 関数型言語で飯を喰う

第6章 オススメの開発/設計テクニック ——「関数型/Haskellっぽい」プログラムの設計/実装,考え方

6.1 動作を決める ——テストを書こう

  • テスト,その前に
  • テストのためのライブラリ
  • doctest/QuickCheckによるテスト
    • doctestの導入
    • doctestを使う
    • QuickCheckを併用する

6.2 トップダウンに考える ——問題を大枠で捉え,小さい問題に分割していく

  • ランレングス圧縮(RLE)
    • 関数の型を決める
    • テストを書く
    • 「らしからぬ」コード
    • 「らしい」コード
    • トップダウンに設計/実装する
    • 型から関数を検索する ——型情報で検索できる「hoogle」
    • 設計/実装を進める
    • hlintで仕上げる ——よりHaskellらしいコードにするために
    • さらなる仕上げ ——もっとシンプルに
    • 今回の例から学ぶ,設計/実装,考え方の勘所
  • 数独
    • ソルバの型を考える
    • 盤面状況を扱うデータ構造を決める
    • 何をすると数独が解けるか
    • まだ数値が埋まっていないマスの候補を選ぶ
    • マスに入れることのできる数値の候補を選ぶ
    • 入れることのできる数値の候補が最も少ないマスを選ぶ

6.3 制約を設ける ——型に制約を持たせる

  • 制約をどのように表現するか
  • 2の冪乗を要求するインタフェース
  • 2の冪乗という制約を持った数の型
  • 可視性を制御して性質を保護する
    • 命令型言語で型に制約を持たせる ——C++の例

6.4 適切な処理を選ばせる ——型と型クラスを適切に利用し,型に制約を記憶させる

  • 複数のエスケープ
    • 変換履歴を持った文字列の型
    • 変換されているかもしれない文字列のクラス
    • エスケープ方法の持つべき性質
    • 各エスケープを定義する
    • モジュールを利用してみる

6.5 より複雑な制約を与える ——とても強力なロジックパズルの例

  • ロジックパズル ——3人の昼食
    • 人間の推論
    • 推論規則を型で表す
    • 推論規則を使って答えを実装する
    • 強力な型がインタフェース設計に与えた力

6.6 まとめ

第7章 Haskellによるプロダクト開発への道 ——パッケージとの付き合い方

7.1 パッケージの利用 ——パッケージシステムCabal

  • Haskellのパッケージシステム
    • 公開されているパッケージを探す ——Hackage
  • 公開されているパッケージを利用する ——cabal編
    • パッケージのインストール
    • パッケージのアンインストール
    • パッケージを利用する
  • 公開されているパッケージを利用する ——Cabal sandbox編
    • sandbox環境を使う

7.2 パッケージの作成 ——とりあえずパッケージングしておこう

  • cabalize ——パッケージング作業
  • サンプルパッケージの作成 ——FizzBuzzライブラリ
    • cabalizeする
    • オススメのディレクトリ構成
    • モジュールの作成と公開
    • ビルド
    • パッケージング
    • バージョニング
    • パッケージの作成方法
    • パッケージのアップロード,バージョンアップ

Column Hackageへ公開しよう

7.3 組織内開発パッケージの扱い ——工夫,あれこれ

  • Cabalを通した利用 ——一番単純な方法
  • Cabal sandboxを通した利用 ——パッケージデータベースを共有しない方法
  • 組織内Hackageサーバの利用
  • パッケージを分けない

7.4 利用するパッケージの選定 ——依存関係地獄,選定の指針

  • 依存関係地獄
    • Haskellにおける依存関係地獄
  • パッケージ選定上,有望な性質
    • コアに近いパッケージ
    • 枯れたパッケージ
    • シンプルなパッケージ
    • 依存関係が少ないパッケージ

Column 「バージョン上限」を設ける利点

    • 依存関係が広いパッケージ

Column Cabal sandboxの光と影 ——「パッケージレベルでの組み合わせやすさ」は,いかに?

    • インタフェースが安定しているパッケージ

7.5 依存パッケージのバージョンコントロール ——パッケージごとにどのバージョンを選択するか

  • バージョンの選定および固定について
    • 1 各OSのパッケージシステムに用意されているものを使う
  • 1 Cabalでローリングアップデートポリシーを定めて
  •  逐次更新していく
    • 3 Stackageに用意されているものを使う

7.6 バージョン間差の吸収 ——バージョン間の差分の検出から

  • 複数開発環境の共存
    • Dockerを使う
    • Stackを使う
    • CIサービスを使う
  • インタフェースが安定しないパッケージの扱い方

Column Stackage/Stackを使う上での注意

7.7 まとめ

Column HaskellでのWebアプリケーション作成 ——より一層,複雑な文脈を表現するモナドの必要性

第8章 各言語に見られる関数プログラミングの影響 ——Ruby,Python,Java,JavaScript,Go,Swift,Rust,C#,C++

8.1 変数を定数化できるか ——変更を抑止する

  • 変数を定数修飾する
  • メソッドを定数修飾する

8.2 関数の扱いやすさ ——関数/ラムダ式,変数への代入,関数合成,部分適用,演算子

  • 各言語における関数/ラムダ式
  • 変数への代入
    • 呼び出し方の差異 ——Rubyの例
    • [関数ではない点1]Pythonのラムダ式 ——参照する環境の影響
    • [関数ではない点2]Javaのラムダ式 ——定数制約の検査
    • [関数ではない点3]C++のラムダ式 ——キャプチャ
  • 「関数」を定義するポイント
  • 関数合成
  • 部分適用
    • Rubyの部分適用
    • C++,Pythonの部分適用
    • Goの部分適用
  • 演算子
    • Swiftの演算子定義 ——オペレータ関数
    • Rubyの演算子定義

8.3 データ型定義とパターンマッチ ——Rust,Swift

  • データ型定義とパターンマッチの例
  • 網羅性検査
  • 再帰的な構造

8.4 型システムの強化 ——静的型付けと型検査,型推論

  • 静的型付けの導入
  • 型推論の採用

8.5 リスト内包表記 ——Python,C#のLINQ

  • Pythonのリスト内包表記
  • C#のリスト内包表記 ——LINQ

8.6 モナド ——Java 8,Swift

  • Swiftのモナド相当のインタフェース

Column Python関数プログラミングHOWTO

  • Stateモナド相当の実装例

8.7 コンパイル時計算 ——C++テンプレート

  • C++テンプレートによる関数プログラミング
  • C++テンプレートによるデータ型定義
    • 自然数
    • リスト
  • C++テンプレートによる関数定義
  • C++テンプレートの評価戦略
  • C++テンプレートの限界

8.8 まとめ

Column Safe navigation operator

Appendix

A.1 関数型言語が使えるプログラミングコンテストサイト ——ゲーム感覚で挑戦

  • [入門]プログラミングコンテスト
  • Anarchy Golf
  • AtCoder
  • CodeChef
  • Codeforces
  • SPOJ

A.2 押さえておきたい参考文献&参考情報 ——次の1手。さらに深い世界へ...

  • 関数プログラミングについて
  • Haskellについて
  • 型システムについて
  • 圏論について

著者プロフィール

大川徳之(おおかわのりゆき)

東京大学計数工学科数理情報工学コース,東京大学大学院情報理工学系研究科数理情報学専攻,卒業。キヤノンソフトウェア㈱を経て,㈱朝日ネットにて,HaskellでのWebアプリケーション開発や,開発環境/インフラの構成管理などに携わっていた。そろそろどうにかしてAgdaで仕事ができないものか虎視眈々と隙を窺っている。バージョンアップ毎にだんだんと増えていくGHCのコンパイル時間が最近の悩み。