プログラミング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)]
文字列
String
は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ループ的な使い方もできる。
例:
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)]
例:
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]