リスト

リストは[a]の形で示される。文字列の型に現れる[Char]はリストだったんだね。
Char自体は次のように表せるよ。

Prelude> :t 'a'
'a' :: Char

リストの中身は同じ型でなくてはいけないんだ。

Prelude> :t [1,2.0]
[1,2.0] :: (Fractional a) => [a]
Prelude> :t [True,'a']

<interactive>:1:6:
    Couldn't match `Bool' against `Char'
      Expected type: Bool
      Inferred type: Char
    In the list element: 'a'

数値なら全てが表せるクラスに制約される型になるし、型が違っていれば文句を言われる。
そのかわり、便利な表現が利用できる。

Prelude> [1..10]
[1,2,3,4,5,6,7,8,9,10]

リスト中に..があると、単純な置き換えが出来る場合は補完してくれるんだ。
他にはこんなこともできる。

Prelude> ['a','d'..'z']
"adgjmpsvy"

最後の要素を書かないと無限リストになる。
さすがに無限リストを表示させようとすると大変になるから、部分的に表示する方法がある。

Prelude> take 20 ['A','E'..]
"AEIMQUY]aeimquy}\129\133\137\141"

なんか変な風になったなあ。順番を文字コードで考えてるのかな。

Prelude> :t '\DEL'
'\DEL' :: Char

まあ、これは必要になったら調べよう。
また、もうちょっと複雑なことがしたかったら、こんな風にもかける。

Prelude> [x|x <- [True,True,False,False,True,False] , x == True]
[True,True,True]

リスト内に|をおいて、左に変数、右に条件を書くと、条件にあったもののリストを作ってくれる。
数学でもこういう表現があるよね。
<-は新しい記号だけど、入力するような演算子じゃないかな。記号だと見た目でわかるけど、調べにくいのが難点だよね。
このリストは合致する項目の数を数えるのに使えそうだね。

mod x y で、xをyで割った余りが分かるんだけど、これを使って複雑な条件のリストを作ってみよう。

Prelude> take 20 [x|x <- [1..] , mod x 3 == 0 , mod (x*x) 7 == 2]
[3,18,24,39,45,60,66,81,87,102,108,123,129,144,150,165,171,186,192,207]

条件は,で並列に書くんだね。なんで&&じゃないんだろう。まあいいか。
こんな意味の分からないリストでもちゃんと作ってくれるね。

左側はタプルでもいいし、式を書いても良いみたいだ。複数の変数を与えるとこんな風になるよ。

Prelude> take 10 [(x*x,y) |x <- [1..] , y <- ['a','b','c']]
[(1,'a'),(1,'b'),(1,'c'),(4,'a'),(4,'b'),(4,'c'),(9,'a'),(9,'b'),(9,'c'),(16,'a')]


また、リストは結合したり、並び替えたり、操作が柔軟に出来る。

Prelude> reverse [1,3..15]
[15,13,11,9,7,5,3,1]
Prelude> [1,4..12] ++ [30 .. 35]
[1,4,7,10,30,31,32,33,34,35]

長さが変わっても型が同じなのがポイントだね。
もっと複雑な操作は別の項目でやろう。

表現が柔軟なタプル、操作が柔軟なリスト。意味を取りやすい型とクラス
そして、それらを操作するための関数。これらを使ってデータ構造を作るのがhaskellの特長だね。

次は他の分岐と合流して入出力を見てみよう。

タグ:

+ タグ編集
  • タグ:
最終更新:2007年09月27日 08:06