すごいH本の覚え書き 第1章「はじめの第一歩」

積読してた「すごいHaskellたのしく学ぼう!」(通称すごいH本)を引っ張り出してきて読み始めたので、備忘録的に章ごとに読んだ内容を覚え書きしていこうと思う。

リスト操作

リスト操作をするための一般的な関数の紹介

  • head

リストの先頭の要素を取ってくる

head [1,2,3]
=> 1
  • tail

リストの先頭を除いた要素を残りのリストを返す

tail [1,2,3]
=> [2,3]
  • last

リストの最後の要素を返す

last [1,2,3]
=> 3
  • init

リストの最後の要素を除いた残りのリストを返す

init [1,2,3]
=> [1,2]
  • length

リストの長さを返す

length [1,2,3]
=> 3
  • null リストが空かどうかを返す
null []
=> True
null [1,2,3]
=> False
  • reverse リストを逆順にする
reverse [1,2,3]
=> [3,2,1]
  • take 数とリストを引数に取り、先頭から指定した数だけリストから取ってくる
take 2 [1,2,3]
=> [1,2]
  • drop

takeとは逆に、先頭から指定した数だけ削除したリストを返す

drop 2 [1,2,3]
=> [3]
  • maximum, minumum

最大値、最小値を返す

maximum [1,2,3]
=> 3
minimum [1,2,3]
=> 1
  • sum リストの要素の総和を返す
sum [1,2,3]
=> 6
  • リストの要素の積を返す
product [1,2,3]
=> 6
  • elem 数とリストを引数に取り、指定した数がリストに存在するかどうかを返す。バッククォートを付けて中置関数として適用する方が多い。
elem 2 [1,2,3]
=> True
5 `elem` [1,2,3]
=> False

同じ要素を繰り返す系の関数

  • cycle リストを受け取り、そのリストを無限に繰り返すリストを作成する。Haskellは遅延評価で処理時に必要な分だけが評価されるため、メモリが溢れる心配はしなくても良い。
cycle [1,2,3]
#=> [1,2,3,1,2,3,1,2,3.....]
  • repeat 数を受け取り、その数を無限に繰り返すリストを作成する。
repeat 5
#=> [5,5,5,5,5,5,5,5,5,.......]
  • replicate リストの長さと複製する要素を引数に取り、その長さ分のリストを作成する。
replicate 3 5
[5,5,5]

レンジ

列挙できる要素の組み合わせでリストを作れる。

[1..5]
# => [1,2,3,4,5]
['a'..'z']
# => ['a','b','c','d'....]

最初にパターンを記述することで等差数列を作ることも可能。

[3,6..10]
#=> [3,6,9,12,15,18]

リスト内包表記

リストのフィルタリング、変換、組み合わせを行うための方法。集合の内包的記法に近い。

[x*2 | x <- [1..3]]
#=> [2,4,6]

[1..3] の各要素をxに束縛し、順にx*2の処理を行っていく。

カンマ区切りで条件を追加することもできる。

[x*2 | x <- [1..3], x*2>5]
#=> [6]

タプル

リストは単一の型の要素でしか構成することはできない。複数の型の要素をセットにして扱うためにはタプルを使う必要がある。

("hoge", 1, True)

fstで一つ目の要素、sndで二つ目の要素を取ってくる、

fst ("hoge", 1)
#=> "hoge"
snd ("hoge", 1)
#=> 1

zipで二つのリストを取り、それらをペアにしたリストを作ることができる。二つのリストの長さが違くても良く、その場合は小さい方に合わせて切り捨てられる。

zip ['a', 'b', 'c'] [1,2,3]
#=> [('a',1), ('b', 2), ('c',3)]
zip ['a', 'b', 'c'] [1,2]
#=> [('a',1), ('b', 2)]

感想

リスト内包表記は自分が触ってきた他言語にはなかったのでかなり独特に見えたが、構文的には分かりやすいと思った(他の関数型言語でもあったりするのだろうか)。慣れが必要だが、使いこなすとかなり強力な武器になりそう。