ようやく初校校了が見えてきたので、ふつけるの情報を出しておきます。 発売日はいまのとこ 5 月末で変わらず。
章目次 (数字の単位は KB、およそ 1KB == 1 ページ)
第一部: チュートリアル 1. 27 intro ........... Haskell最初の一歩 2. 27 tut1 ............ Haskellの基礎(1)関数とリスト 3. 28 tut2 ............ Haskellの基礎(2)型と高階関数 4. 17 tut3 ............ Haskellの基礎(3)演習 第二部: リファレンスみたいな 5. 24 lazy ............ 遅延評価 6. 26 value ........... 基本的な値 7. 31 expr ............ 基本的な構文 8. 24 function ........ 関数 9. 29 type ............ 型と型クラス 10. 10 module .......... モジュール 11. 14 monad ........... モナド 第三部: 気持ちは実戦 12. 17 parsec .......... 実習(1)Wikiパーサ 13. 11 wiki ............ 実習(2)LazyLines 14. 2 after ........... 本書を読み終えたあとに Total 280 Kbytes
分量は、ふつりなと同じ判型で 300 ページ強です。
第一部は Haskell 初心者ができるだけ馴染めることを優先しました。 第二部は本として使うのに便利であることを優先しました。 第三部は読んでおもしろいことを優先しました。
特徴。 5 章で置き換えモデルを使って遅延評価の実装について話したり、 8 章で point-free style について一節分えんえんと語ったり、 12 章でパーサコンビネータを容赦なく使ってたり (そのうえ作ったり) するところが特徴だろうなあ。
詳細目次
1 Haskell最初の一歩 intro.re 507 1 本書の概要 290 1 対象環境 4 2 Haskellとは 21 3 なぜHaskellか 8 4 Haskellの利点(1)柔軟にプログラミングできる 45 5 Haskellの利点(2)コンパイル時の型チェックが強力 20 6 Haskellの利点(3)読みやすい 36 7 Haskellの利点(4)遅延評価が基本 28 8 Haskell 7つの壁 83 1 「みんなHaskellは難しいって言ってる」 2 「ドキュメントを読んだらいきなり参照透明性がどうとか……」 3 「だって数学できないと使えないんでしょ?」 4 「インストールで挫折した」 5 「型エラーが大量に出て恐い」 6 「型が難しい」 7 「モナドがわからない」 9 本書の構成 33 2 Haskell処理系の準備 69 1 GHC 8 2 Windowsでのインストール 26 3 Linuxでのインストール 32 3 Hello, World! 136 1 hello.hs 10 2 ghcコマンド, runghcコマンド, ghciコマンド 5 3 Windowsでのコンパイル 19 4 Linuxでのコンパイル 15 5 runghcコマンドでHello, World! 19 6 ghciコマンドでHello, World! 53 7 コラム:Haskellのリファレンスマニュアル 13 4 本章のまとめ 5 2 Haskellの基礎(1)関数とリスト tut1.re 687 1 チュートリアルの概要 25 2 mainアクションと関数適用 50 1 hello.hs 9 2 変数の定義 2 3 mainアクション 9 4 関数の適用 13 5 文字列リテラル 3 6 hello.hsのまとめ 12 3 入出力の基本 196 1 catコマンド 41 2 cat.hs 32 3 getContentsアクション 2 4 putStr関数 3 5 レイアウト 21 6 do式 15 7 入出力と「<-」 9 8 変数の参照 8 9 cat.hsのまとめ 19 10 catコマンドの謎 35 11 cat.hsのまとめ 6 4 リスト処理の基本(1)countlineコマンド 187 1 リスト 21 2 リストリテラル 40 3 countlineコマンド 18 4 countline.hs 9 5 「$」演算子 33 6 lines関数 15 7 length関数 17 8 print関数 4 9 countline.hsのまとめ 18 10 コラム:変数名の慣習について 8 5 リスト処理の基本(2)headコマンド 124 1 headコマンド 22 2 head.hs 10 3 2引数の関数適用 15 4 関数の定義 12 5 firstNLines関数の定義 16 6 unlines関数 13 7 take関数 12 8 head.hsのまとめ 22 6 リスト処理の基本(3)tailコマンド 77 1 tailコマンド 19 2 tail.hs 17 3 reverse関数 9 4 tail.hsのまとめ 30 7 本章のまとめ 9 8 練習問題 14 1 words関数 10 3 Haskellの基礎(2)型と高階関数 tut2.re 722 1 型と値 174 1 静的型チェックと型推論 13 2 基本的な型 28 3 関数の型 23 4 型変数 36 5 複数の型変数 31 6 型の宣言 22 7 これまでに紹介した関数の型 18 2 高階関数 244 1 値としての関数 17 2 高階関数とは 14 3 map関数 21 4 expandコマンド 27 5 expand.hsバージョン0 18 6 if式 23 7 「==」演算子 15 8 expand.hsバージョン0のまとめ 29 9 expand.hsバージョン1 19 10 concat関数 24 11 expand.hsバージョン1のまとめ 35 3 パターンマッチ(1) 132 1 expand.hsバージョン2 21 2 パターンマッチ 43 3 concatMap関数 28 4 replicate関数 15 5 expand.hsバージョン2のまとめ 23 4 パターンマッチ(2) 152 1 map関数 9 2 リストに対するパターンマッチ 33 3 関数の再帰定義 24 4 map関数の定義のまとめ 19 5 map関数の適用 58 6 コラム:再帰と高階関数 6 5 本章のまとめ 13 6 練習問題 2 4 Haskellの基礎(3)演習 tut3.re 453 1 コマンドライン引数の処理とモジュール 98 1 echoコマンド 9 2 echo.hs 13 3 モジュールとimport宣言 19 4 Mainモジュール 8 5 Preludeモジュール 9 6 unwords関数 14 7 System.getArgsアクション 11 8 echo.hsのまとめ 14 2 演習 295 1 fgrepコマンド 12 2 fgrep.hs 25 3 mainアクションとfgrep関数の定義 25 4 head関数 19 5 tail関数 21 6 filter関数 15 7 fgrep関数とwhere節 28 8 match関数の実装 58 9 any関数 17 10 List.tails関数 16 11 List.isPrefixOf関数 18 12 fgrep.hsのまとめ 27 13 コラム:もっと簡潔に書きたい 11 3 本章のまとめ 26 4 練習問題 29 1 List.sort関数 11 2 List.group関数 14 5 遅延評価 lazy.re 594 1 遅延評価とは 276 1 評価とは 10 2 置き換えモデル 36 3 最内簡約と最外簡約 28 4 グラフ簡約 41 5 ifを関数として書く 28 6 データ構造の遅延評価 44 7 遅延評価の限界 22 8 遅延評価とパターンマッチ 22 9 コラム:置き換えモデルと参照透明性 43 2 遅延評価のシミュレーション 179 1 myIf関数の評価 45 2 map関数の評価 119 3 map関数の評価に関する補足 13 3 遅延評価の利点と欠点 130 1 遅延評価の利点 5 2 利点(1)計算量を削減できる 46 3 利点(2)無限の長さのリストが扱える 28 4 利点(3)インターフェイスを統一できる 24 5 遅延評価の欠点 5 6 欠点(1)思った順番で操作を実行するのが難しい 7 7 欠点(2)デバッグしにくい 13 4 本章のまとめ 5 6 基本的な値 value.re 734 1 本章の構成 9 2 真偽値 26 1 Bool型 5 2 not関数 6 3 (&&)関数 7 4 (||)関数 7 3 数値 119 1 整数型 38 2 浮動小数点数型 19 3 数値の演算 55 4 これ以外の数値型 6 4 文字と文字列 96 1 文字型 36 2 文字列型 7 3 文字に関する関数 4 4 文字種のテスト 19 5 大文字・小文字の変換 15 6 文字と整数との変換 14 5 タプル 87 1 タプルとは 18 2 ユニットとは 5 3 タプルを扱う関数 3 4 fst関数 13 5 snd関数 13 6 zip関数 22 7 unzip関数 12 6 リスト 178 1 リストとは 27 2 「:」演算子 27 3 リストの数列表記 36 4 リストに関する関数 8 5 null関数 18 6 (++)関数 18 7 リスト内包表記 43 7 実習:cat -nコマンド 194 1 cat -nコマンド 19 2 catn.hs 22 3 numbering関数の実装 23 4 zipLineNumber関数の実装 25 5 format関数の実装 26 6 show関数 9 7 rjust関数の実装 40 8 catn.hsのまとめ 28 8 本章のまとめ 6 9 練習問題 14 7 基本的な構文 expr.re 823 1 コメント 72 1 1行コメント 19 2 ブロック形式のコメント 17 3 Literate形式 35 2 レイアウト 122 1 ブレース構文 34 2 レイアウト 30 3 コードブロックのネスト 44 4 式の継続 12 3 if式 29 1 if式の文法 7 2 if式のコーディングスタイル 21 4 パターンマッチ 228 1 パターンマッチとは 29 2 さまざまなパターン 10 3 変数パターン 9 4 「_」パターン 11 5 リテラルパターン 12 6 タプルパターン 19 7 リストパターン 25 8 データコンストラクタによるパターン 16 9 遅延パターン 15 10 「@」パターン 18 11 ガード 45 12 パターンマッチとガード 18 5 case 式 48 1 case式とは 33 2 case式とレイアウト 14 6 関数定義 176 1 関数の定義 21 2 識別子の規則 18 3 二項演算子の定義 14 4 二項演算子の規則 21 5 前置形式と二項演算子の変換 18 6 演算子の優先順位と結合性 43 7 Haskellでの演算子優先順位と結合性 20 8 演算子優先順位と結合性の宣言 20 7 定義と束縛 117 1 let式 25 2 where節 27 3 let式とwhere節の違い 19 4 変数のシャドウイング 22 5 定義中での相互参照 11 6 パターン束縛 12 8 本章のまとめ 5 9 練習問題 21 1 splitAt関数 18 8 関数 function.re 631 1 値としての関数 91 1 関数束縛 18 2 高階関数 9 3 無名関数 29 4 無名関数と高階関数 15 5 無名関数でのパターンマッチ 19 2 関数合成 102 1 関数合成とは 22 2 (.)関数 24 3 関数合成の使用例 55 3 部分適用 185 1 部分適用とは 54 2 Haskellでの関数と適用 30 3 セクション 32 4 セクションと(-)関数 8 5 部分適用の応用(1)高階関数と部分適用 22 6 部分適用の応用(2)変数の削減 38 4 Point-Free Style 216 1 Point-Free Styleとは 30 2 Point-Free head.hs 47 3 Point-Free fgrep.hs(1) 53 4 Point-Free fgrep.hs(2) 76 5 Point-Free Styleとコードの読みやすさ 8 5 本章のまとめ 6 6 練習問題 23 1 dropWhile関数 14 9 型と型クラス type.re 630 1 静的型チェックと型推論 97 1 型 9 2 静的な型チェック 6 3 型推論 29 4 型宣言 20 5 式に対する型宣言 10 6 多相型 22 2 代数的データ型 279 1 代数的データ型とdata宣言 11 2 構造体スタイル 36 3 パターンマッチによるフィールドへのアクセス 18 4 フィールドラベル 27 5 フィールドアクセサ 10 6 フィールドの更新 15 7 多相的な型の宣言 20 8 型コンストラクタとデータコンストラクタ 16 9 列挙型スタイル 34 10 共用体スタイル 39 11 再帰的な型 39 12 一般のdata宣言 13 3 型の別名と付け替え 48 1 type宣言 21 2 newtype宣言 25 4 型クラス 195 1 型クラスとは 15 2 型クラスの例 25 3 クラスメソッド 7 4 多重定義 14 5 型クラスの継承 22 6 class宣言 28 7 継承を含むclass宣言 15 8 instance宣言 15 9 deriving宣言 21 10 主要な型クラス 14 11 コラム:型クラスとオブジェクト指向のクラス 18 5 本章のまとめ 6 6 練習問題 1 10 モジュール module.re 214 1 モジュールの基本概念 47 1 モジュールとは 9 2 基本的なモジュール 28 3 階層化ライブラリ 9 2 モジュールの定義とエクスポート 90 1 module宣言 12 2 エクスポートするエンティティの限定 20 3 データコンストラクタのエクスポート 35 4 モジュールのエクスポート 14 5 Mainモジュール 8 3 インポート 70 1 import宣言 13 2 特定エンティティのインポート 14 3 特定エンティティのインポート防止 11 4 qualified構文 18 5 as構文 12 4 本章のまとめ 3 11 モナド monad.re 368 1 モナドとは何か 49 1 モナド 21 2 Monadクラス 13 3 モナド則 14 2 Maybeモナド 76 1 Maybeとは 31 2 Maybeをモナドとして使う 20 3 Maybeモナドの仕組み 24 3 リストモナド 36 1 リストモナドの目的 28 2 リストモナドの実例 0 3 リストモナドの仕組み 7 4 モナドの構文 94 1 do式 11 2 do式とlet 29 3 let節 26 4 do式とif 27 5 IOモナド 102 1 IOモナドの目的 17 2 IOでの(>>=) 32 3 IOでの(>>) 13 4 入出力以外でのIOモナド 16 5 IOモナドの問題 11 6 Debug.Trace.trace関数 12 6 それで結局モナドって何? 3 7 本章のまとめ 2 8 練習問題 2 12 実習(1)Wikiパーサ parsec.re 526 1 第3部の目的 40 1 Wikiとは 17 2 Wikiの構造 1 3 なぜWikiを作るのか 22 2 Wikiパーサ 19 1 Wiki記法 2 2 LazyLinesのWiki記法 8 3 実装の概要 8 3 インラインパーサ 43 1 パーサコンビネータとは 4 2 Text.ParserCombinators.Parsecモジュール 1 3 パーサコンビネータの仕組み 0 4 インラインパーサ 36 4 パラメタライズされた文字列 66 1 HTML 28 2 ParameterizedText 1 3 ParameterizedTextの実装 37 5 ブロックレベルパーサ 66 1 ベタ書き版compile関数 42 2 パーサコンビネータ版compile関数 22 6 行指向パーサの作成 118 1 data Parser 23 2 パーサコンビネータの仕組み 8 3 選択演算子の実装 11 4 satisfy関数 10 5 eof関数 19 6 many関数 12 7 many1関数 8 8 LineParser 25 9 モナドの利点 2 7 ブロックのコンパイル 170 1 パース開始 19 2 キャプション 6 3 定義リスト 12 4 段落 10 5 List.intersperse関数 23 6 プリフォーマットリスト 52 7 リスト 48 8 本章のまとめ 0 13 実習(2)LazyLines wiki.re 296 1 設計の概要 74 1 本章の目標 6 2 まず最初に決めること 5 3 コラム:LazyLinesという名前の由来 6 4 ポリシー 7 5 Haskellでのウェブアプリケーション開発 21 6 設計 4 7 モデル:データベース 9 8 ビュー:テンプレート 2 9 ビュー:パーサ 1 10 コントローラ:リクエストの処理 6 11 ファイル構成 7 2 データベースの実装 75 1 Databaseモジュール 7 2 Database型 15 3 データベースの簡単な操作 15 4 ファイルの書き込み 38 3 リクエスト-レスポンス 0 4 Wikiのリクエスト-レスポンス 109 5 HTMLテンプレート 1 1 仕様 1 6 PathUtils.hs 34 1 init関数 18 2 last関数 16 7 この章のまとめ 0 14 本書を読み終えたあとに after.re 34 1 Haskellの開発体制 3 2 アプリケーション 1 3 ライブラリ 2 4 開発ツール 11 5 書籍 9 6 ウェブ上の情報 2 7 本章のまとめ 1
(17:06)
うは。無駄に凝りすぎのディテールが最高。 ここまできっちりできてるとフツーに役立つなあ。 結城さんインタビューも (まだ読んでないけど) おもしろそうだ。
(17:07)
こないだまでページが増えねーって苦しんでたのに、 今度はページが増えすぎて苦しみまくり。
~/c/stdhaskell % list 1. 27 intro .......... Haskell最初の一歩 2. 27 tut1 ........... Haskellの基礎(1)関数とリスト 3. 28 tut2 ........... Haskellの基礎(2)型と高階関数 4. 17 tut3 ........... Haskellの基礎(3)演習 5. 24 lazy ........... 遅延評価 6. 26 value .......... 基本的な値 7. 31 expr ........... 基本的な構文 8. 24 function ....... 関数 9. 31 type ........... 型と型クラス 10. 11 module ......... モジュール 11. 22 monad .......... モナド 12. 30 wiki ........... LazyLinesの開発 13. 16 parsec ......... Wiki記法パーサとパーサコンビネータ 14. 3 after .......... 本書を読み終えたあとに Total 309 Kbytes
12 章が増えすぎ。これでも 15KB くらい削ってるんだよ……。 書いては削り、書いては削り……。そのうえ、まだ 13 章も爆発する予定。
まずいな。これは本当にまずいな。 目次とまえがきと付録と索引を入れたらいったいどうなるんだ。 下手すると 350 ページくらいになってしまう。 いや実はいつも 50 ページくらいオーバーするんだが。
(05:46)
もうちょいで完成……
~/c/stdhaskell % list aamine@serenade 1. 27 intro .......... Haskell最初の一歩 2. 27 tut1 ........... Haskellの基礎(1)関数とリスト 3. 28 tut2 ........... Haskellの基礎(2)型と高階関数 4. 17 tut3 ........... Haskellの基礎(3)演習 5. 24 lazy ........... 遅延評価 6. 26 value .......... 基本的な値 7. 31 expr ........... 基本的な構文 8. 24 function ....... 関数 9. 31 type ........... 型と型クラス 10. 11 module ......... モジュール 11. 22 monad .......... モナド 12. 34 wiki ........... Wikiエンジンの開発 13. 31 parsec ......... Wiki記法パーサの開発 14. 5 after .......... 本書を読み終えたあとに Total 331 Kbytes
13 章はあらかた書き終わった。 14 章は速攻で終わりそうというか早くも終わりかけてる。 これから夕飯食ったら 13 章を見直して、14 章を書き上げて、 両方まとめてレビューに流す予定。
確実に、今夜中に、決着するぜ!
(02:16)
全章コンプリーツ。あるいはコンプリーテッド。
1. 27 intro .......... Haskell最初の一歩 2. 27 tut1 ........... Haskellの基礎(1)関数とリスト 3. 28 tut2 ........... Haskellの基礎(2)型と高階関数 4. 17 tut3 ........... Haskellの基礎(3)演習 5. 24 lazy ........... 遅延評価 6. 26 value .......... 基本的な値 7. 31 expr ........... 基本的な構文 8. 24 function ....... 関数 9. 31 type ........... 型と型クラス 10. 11 module ......... モジュール 11. 22 monad .......... モナド 12. 34 wiki ........... Wikiエンジンの開発 13. 33 parsec ......... Wiki記法パーサの開発 14. 7 after .......... 本書を読み終えたあとに Total 335 Kbytes
今回は本当に各方面に御迷惑をおかけしましたが、 おかげさまでなんとか脱稿できそうです。 ありがとうございました。
ちなみに出版日は変わらない……と思います。たぶん。
(07:06)
コミットメールを設定中、こんなエラーに遭遇した。
~/c/xxxxx % cvs ci -m updated hello.c /xxxxxxxxxxxxxxxxxxxxx/hello.c,v <-- hello.c new revision: 1.54; previous revision: 1.53 cvs.chroot [commit aborted]: received broken pipe signal
原因: loginfo を実行するときには sh が必要。
うちは chroot 環境なので sh がなくてエラーになっていた。 コミットメール配送用コマンドを自分で書いていたので、 そっちのほうばかり疑ってしまった。
くっそー、chroot jail 内にインタプリタを置きたくない一心で Ruby スクリプトの実行ファイル化までやったのに、 /bin/sh なんてあったら台無しじゃん。 sh なんて何に使ってるんだ。
(04:14)
返信してないレビューが 50 通以上…… orz draft に並ぶメールの山がすげーことに。 やっぱり来たメールには即座に返信していける状況でやっていかないとだめなんだよなあ。 書くほうとしてもそのほうが精神的な負担が減るし、レビュアーにしてみても、 すぐに反応が返ってくるほうが面白いと思うし……。
ああ、つくづく今回はスケジューリングが失敗だった。 こんなに遅くなるとは思ってもいなかったし、 こんなに他の予定と重なりまくるのも想定外だ。
(08:07)
[ruby-list:42032] あたりの、 解析する文法を DSL で記述する話について。
Haskell の Parsec がまさにそれ。Ruby でも、ないわけではない。
例えば、Racc よりも速いぜーと ruby-talk で自慢していた Grammar はそれっぽい。 ただ DSL というよりはオブジェクトを作る感じが強くて、俺は好きになれなかった。
見ためがきれいという点では akr さんの abnf が一番いいと思う。 これは DSL じゃなくて文字列だけど。
るびま 8 号の立石さんの記事にもパーサ関係はいくつか出てたなあ。
http://jp.rubyist.net/magazine/?0008-RLR
今回見なおしてみると、tdp4r と syntax.rb が欲しいものに一番近いかもしれない。 でもどちらももうちょい見ためをすっきりできそうな印象を受ける。 あと syntax.rb は String#+ だの String#- だの定義しちゃうのが嫌だ。
Racc もさ、もう少しなんとかできそうな気はするんだよな。例えば
Racc::Grammar.define { rule program, expr rule expr, '(', expr, ')' _ expr, '+', expr do .... end _ expr, '-', expr do .... end _ expr, '*', expr do .... end _ expr, '/', expr do .... end _ num }
なんてのならすぐに実装できると思うけど。 うーん。ちょっとイマイチかなあ。
(05:44)
Core Duo 入って 12" サイズで 1.5kg 以下で バッテリーが 4 時間もつ Mac ノートはないですかねえ。
タッチパッドを嫌うと、 どうしても Thinkpad X60 になってしまうな。
(19:17)
重さが 1kg 切ってバッテリーが 9 時間もつ Let's Note R4 もいいなあ。 タッチパッド以外は。
まあ、Mac はいいや。 一台くらいは XP もないとまずかろうし。
毒食らわば皿までってことで Office も買おうかと思ったんだけど、 Home だと PowerPoint ないのな。 おれ Excel 使わないから、Word と PowerPoint だけ欲しいんだけど。 あ、そうか、アカデミックパックならもっと安いはずだな。
(19:42)
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
■ きむら [ふむふむ。なんとはなしにakrさんのやつが思い浮かんだのですが、返事には書きませんでした(ちょっと自信なかったので)。おお外しではなかったのですね。ちょっと安心。それとHaskellの勉強を続ける動機ができました(笑)。]
■ KM [callcc を使って, 任意の文脈自由文法が読める LL(∞) パーザが(右再帰の無限ループは回避しないとダメだけど)書けるんではないかなぁと前からぼんやり考えていたのですが、最近この文献が自分の「あとで読む」リストに →
http://d.hatena.ne.jp/sumii/20060413/1144920884]