数学における集合の内包的記法に近い。
# 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]]