kanetaiの二次記憶装置

プログラミングに関するやってみた、調べた系のものをQitaに移して、それ以外をはてブでやる運用にしようと思います。http://qiita.com/kanetai

プログラミングHaskell第5章(リスト内包表記)まとめ

zip

2つのリストを取り、対応する要素をタプルにしたリストを作る。 2つのリストの長さが違う場合は、短い方のリストと同じ長さのリストとして扱う。

pairs :: [a] -> [(a,a)]
pairs xs = zip xs (tail xs) 
-- pairs [1, 2, 3, 4] -----> [(1,2),(2,3),(3,4)]

文字列

StringCharのリストと等価 { (String \equiv [Char] ) }

従って、"abc"::String['a', 'b', 'c']::[Char]の略記となる。

Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> "abcd" !! 2
'c'
Prelude> zip "abc" [1,2,3,4]
[('a',1),('b',2),('c',3)]

リスト内包表記

集合の内包表記のように、Haskellではリスト内包表記ができる。 簡易forループ的な使い方もできる。

例:{ \{1,2,3\} \times \{4,5,6\} = \{(x, y) | x \in \{1,2,3\} , y \in \{4,5,6\} \} }

Prelude> [(x, y)| x <- [1,2,3], y <- [4,5,6]]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
-- 生成器の列挙順を変えると生成される要素の順番が変わる
Prelude> [(x, y)| y <- [4,5,6], x <- [1,2,3]]
[(1,4),(2,4),(3,4),(1,5),(2,5),(3,5),(1,6),(2,6),(3,6)]
-- concat :: [[a]] -> [a]を使うと
concat [[(x, y) | y <- [4,5,6]] | x <- [1,2,3]]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]

例:{ \{(x, y)| x\in\{1,2,3,4\}, y\in\{1,2,3,4\}, x\leq y \} }

Prelude> [(x,y)|x<-[1..4], y<-[1..4], x <= y]
[(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4),(4,4)]
-- 前方の生成器で使った変数を、後方の生成器でも使用できる
Prelude> [(x,y)|x<-[1..4], y<-[x..4]]
[(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,3),(3,4),(4,4)]

例:length :: [a] -> Int

length xs = sum [1 | _ <- xs]

例:positions

positions :: Eq a => a -> [a] -> [Int]
positions x xs = [p | (e,p) <- zip xs [0..(length xs)-1], x == e]
-- positions 1 [1,2,3,1,3,2,1,3,1] ----> [0,3,6,8]