初心者がHaskell をちょっとした思考実験に使えるようになるまでのチェックリストを考えてみた。自分でもまだ達成していない事柄も多いので、これからの学習の目標のようなものだ。
- Hugs のインストール
- Hugs の起動と終了。Linux の場合は、hugs -Evi または hugs -Egedit のように -E オプションでエディタを指定できる。
- Hugs で数式の値を求めることができる。(1+2)*3 の答えを出すようなこと。
- sqrt, mod, sin など標準の関数を使うことができる。また、1+2 と (+) 1 2、mod 4 3 と 4 `mod` 3 のように演算子や関数を前置型や中置型にして使うことができる。
- リストやリストのリストを作成できる。リストの要素はすべて同じ型でないといけないことを理解できる。
- Hugs でリストの操作をする。(:), ++, head, tail, last, init, take, drop, splitAt, zip, concat, sum, product が使える。また、[1..10] が [1,2,3,4,...,10] であることを理解する。
- 文字列はキャラクターのリストであることを理解する。リストに関する関数がそのまま文字列にも使えるのを理解する。
- リストの内包的定義(List comprehension)ができる。
- [1..] が無限リストであることを知る。また、take 10 [1..] のように無限リストを引数にしてもプログラムが暴走しないことを理解する(遅延評価)。
- タプルについて理解する。fst, snd が使える。
- Hugs の :type コマンドを使ってデータや関数の型を調べることができる。
- Hugs の :edit コマンドでエディターを立ち上げ、square x = x * x のような簡単な関数を定義し、エディターを終了し :load コマンドで関数の定義を Hugs に load し、Hugs のプロンプトからそれを実行できる。
- -- と {- -} がコメントであることを理解する。
- エディターで複数行にまたがる長い文字列を記述できる(¥による改行のエスケープが使える。)
- Hugs の :module 関数を使ってプロンプトからアクセスできるモジュールを変更できる。
- 高階関数 map, filter, floldr, foldl, takeWhile, dropWhile, zipWith を使える。また、高階関数の引数にラムダ記法による無名関数を使える。
- ガードを使って値が変数のパターンによって異なる関数、たとえば絶対値などをプログラムできる。
- 階乗の計算のように単純な再帰関数による関数の定義ができる。
- リストの再帰関数、たとえば、リストの要素数を取得する関数をリストのパターンを使ってプログラムできる。
- ワイルドカード _ を使うことができる。
- @ を使ったパターンの記述ができる。
- case を使った関数の定義ができる。
- where 句を使った関数の定義ができる。
- let を使った関数の定義ができる。
- { ; } を使ってブロックを記述できる。
- インデントの意味を理解できる。オフサイドルールが分かる。
- パターンを使って3項以上のタプルの要素を取り出す関数を作ることができる。
- Int型などの基本型を列挙できる。
- 関数のタイプについての a type signature declaration ができる。その時に型変数を使うことができる。例 map :: a -> [a] -> [a]
- 再帰関数で無限リストを定義できる。例 ones = 1 : ones
- Hugs のプロンプトから :load 命令や :module 命令を使ってモジュールを呼び出し、Prelude にない関数を使うことができる。
- import 宣言を使って自分のプログラムにモジュールをインポートできる。
- フィボナッチ数列のプログラムが作れる。
- 素数列のプログラムが作れる。
- クイックソートのプログラムが作れる。
- 順列を列挙するプログラムが作れる。
- 組み合わせを列挙するプログラムが作れる。
- data 宣言を使ってユーザ定義のデータ型を作れる。そのときに deriving 句を使ってデータを Show クラスのインスタンスにすることができる。
- クラスとデータ型の関係が理解できる。class 宣言が何をしているのかを理解できる。
- instance 宣言を使って二分木のデータをShowクラスのインスタンスに登録し、同時に show 関数をオーバーライドして、二分木データの表示形をカスタマイズできる。
- 型コンストラクタとデータコンストラクタの違いが分かる。
- newtype 宣言の意味が分かる。
- データコンストラクタのパターンを使ってデータコンストラクタのフィールドの値を取り出す関数を作ることができる。例 Just a -> a
- 二分木のデータ型を宣言できる。
- 二分木のデータを作ることができる。
- 二分木のノードの値をすべて集めたリストを作るプログラムを作れる。
- show 関数を使っていろいろな型のデータを文字列に変換できる。
- lookup 関数を使って個の関数の戻り値が Maybe モナドであることを確認できる。Maybe モナドのデータコンストラクタが Just a と Nothing であることを理解できる。lookup 関数の出力を次の lookup 関数に >>= 演算子でカスケードに接続できる。return 関数に引数を与えて lookup 関数に >>= 演算子で接続できる。Maybe モナドの使いかたが分かれば、モナド全般の使いかたが分かる。
- putStr 関数を使って文字列を表示できる。
- getLine 関数を使ってプロンプトから一行をとりこみ、putStr を使ってそれを表示するプログラムを作れる。そのときに、do 及び >>= を自由に使うことができる。
- Haskell のプログラムのエントリーが main 関数であることを理解する。
- IOモナドでプログラムするときは関数が必ずIOモナド型の値を返さなければならないことを理解する。
- return a で、IO a 型の値が返されることを理解する。
- IOモナドの関数では、IO a が >>= で渡された時、引数が IO a ではなく、a であることを理解する。
工事中。