一汁三菜

自分が楽しいと思うこと、マラソン、旅行、その他日々の記録をしたい。

第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