by shigemk2

当面は技術的なことしか書かない

リスト内包表記

数学における集合の内包的記法に近い。

# xにリストを代入して、パイプの左側でリストの各要素を2倍して出力する
Main> [x*2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]

# パイプの右側で条件を指定する(述語を指定する、つまりフィルタをかける)
Main> [x*2 | x <- [1..10], x*2 >= 12]
[12,14,16,18,20]

# フィルタかけの別の例 xを7で割って3余るときの数値のみを出力する
Main> [x | x <- [50..100], x `mod` 7 == 3]
[52,59,66,73,80,87,94]

ここから、以下のような関数をファイルで定義する。

-- 要素が奇数で、かつxが10より小さいなら、BOOM 10より大きいならBANGを出力する
boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
Main> boomBangs [7..13]
["BOOM!","BOOM!","BANG!","BANG!"]

# 13 15 19以外の数値を出力
Main> [ x | x <- [10..20], x /= 13, x /= 15, x /= 19]
[10,11,12,14,16,17,18,20]

# リスト同士の演算
Main> [x+y | x <- [1,2,3], y <- [10,100,1000]]
[11,101,1001,12,102,1002,13,103,1003]

# リスト同士の演算 その2
Main> [x*y | x <- [2,5,10], y <- [8,10,11]]
[16,20,22,40,50,55,80,100,110]

# リスト同士の演算 その3 (x*yが50より小さいのを条件とする)
Main> [x*y | x <- [2,5,10], y <- [8,10,11], x*y < 50] 
[16,20,22,40]


Main> let nouns = ["hobo","frog","pope"]
Main> let adjectives = ["lazy","grouchy","scheming"]
Main> adjectives
["lazy","grouchy","scheming"]
Main> nouns
["hobo","frog","pope"]
Main> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]
["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog","grouchy pope","scheming hobo","scheming frog","scheming pope"]
-- lengthを改造(リスト内の全ての要素を1にして、全ての要素を足す=要素の長さを求められる)
length' xs = sum [1 | _ <- xs ]
-- リスト内の大文字の文字列を全て削除
removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]
Main> length [1,2,3]
3
Main> removeNonUppercase "Hahaha! Ahahaha!"
"HA"
Main> removeNonUppercase "IdontLIKEFROGS"
"ILIKEFROGS"
# リストから偶数を取り除く
Main> let xss = [[1,3,5,2,3,1,2,4,5], [1,2,3,4,5,6,7,8,9], [1,2,4,2,1,6,3,1,3,2,3,6]]
Main> xss
[[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
Main> [[x | x <- xs,even x] | xs <- xss]
[[2,2,4],[2,4,6,8],[2,4,2,6,2,6]]