第3章 Haskellの基礎(2)型と高階関数
第1部な割にはペースが遅いので、ペースアップしていきます。
型
関数の型宣言は、以下のような形式。
関数名 :: 引数の型1 -> 引数の型2 -> ... -> 戻り値の型
型が任意の型で良い時は、多相型の変数を使う。例えば、
map :: (a -> b) -> a -> b
代表的な型は、
- Char
- 文字
- Int
- 整数
- Bool
- 真偽値
- []
- リスト
高階関数
関数を引数に取るような関数。Rubyで言う所のProcだと思うけど、Procとはちょっと勝手が違う気がする。Rubyでは普通のメソッドを引数にするような事は出来なくて、イテレータ経由にしないとダメだし。
閑話休題。例として挙げられていたのはmapだった。
print $ map reverse [ "foo", "bar", "baz" ] → [ "oof", "rab", "zab" ]
パターンマッチ
宣言的に関数を記述する為の仕組み。reverse関数を模倣するmyreverse関数をパターンマッチで書くと、こんな感じ。
myreverse2 :: [a] -> [a] -> [a] myreverse2 [] ys = ys myreverse2 (x:xs) ys = myreverse2 xs (x:ys) myreverse :: [a] -> [a] myreverse xs = myreverse2 xs []
(x:xs)みたいにすると、xにリストの先頭、xsにリストの残りが入る。要するにSchemeで言うところのcarとcdr。
if文
if 条件式 then 真の時の式 else 偽の時の式
条件式がTrueの時に「真の時の式」が、Falseの時に「偽の時の式」が評価される。条件式がそれ以外の値の時は、型エラーが出る。真偽それぞれの式の値が、if式の値となる。
本章で出てきた主な関数
- concat xs
- [xs]をxsにする (一段階だけリストを外す)
- replicate n x
- xがn個入ったリストを返す
- ==
- 二つの値が等しい時にTrueを返す
練習問題
replaceA :: Char -> Char replaceA 'a' = 'A' replaceA 'A' = 'a' replaceA c = c swapa :: String -> String swapa cs = map replaceA cs main = do cs <- getContents putStr $ swapa cs