「プログラミング Haskell」 読書メモ

プログラミング Haskell 第5章 リスト内包表記

ghci> [x^2|x<-[1..5]]  ーー 1 から 5 のリストの要素 x について二乗した値
[1,4,9,16,25]

ghci> [(x,y)|x<-[1..3],y<-[4,5]]
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]

ghci> [(x,y)|y<-[4,5],x<-[1..3]]
[(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)]

-- 重複のない組み合わせ
ghci> let pairing n = [(x,y)|x<-[1..n],y<-[x..n]]
ghci> pairing 1                                  
[(1,1)]
ghci> pairing 2 
[(1,1),(1,2),(2,2)]
ghci> pairing 3
[(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]

-- リストを連結する関数をリスト内包表記で。
ghci> let concat xss = [x| xs<-xss, x<-xs]            
ghci> concat [[1,2,3],[4,5,6]] 
[1,2,3,4,5,6]
-- リストを深くするとxsssの要素xssについて、xssの要素xsについて,xsの要素xが
-- 取り出されるというイメージ。
ghci> let concat3 xsss = [x|xss<-xsss, xs<-xss, x<-xs]
ghci> concat3 [[[1,2,3],[4,5,6]]]                     
[1,2,3,4,5,6]

-- _ を使ってタプルのリストの fst を取り出す。
ghci> let firsts ps = [x|(x,_)<-ps]       
ghci> firsts [(1,"abc"),(2,"def")] 
[1,2]
-- fstを使うと。
ghci> let firsts2 ps = [fst x|x<-ps]
ghci> firsts2 [(1,"abc"),(2,"def")] 
[1,2]

-- リストの要素を数字の1に置き換え、そのリストの数を合計すると
-- リストの長さになるという求め方
ghci> let mylength xs = sum [1|_<-xs]
ghci> mylength [1,2,3,4,5]           
5
ghci> [1|_<-[1..5]]
[1,1,1,1,1]
ghci> sum [1,1,1,1,1]
5

  • 他の言語でもリスト内包表記が出来るようです。
    • 10.14 srfi-42 - 先行評価的内包表記
    • Pythonの技法:リストの内包表記
    • Clean入門(11):内包表記

      ピタゴラスの三角形になる整数の組み合わせを抽出する例がありました。
      ちょっと修正してHaskellで。

      triangles max = [(a,b,c) | a <- [1..max]
                               , b <- [a..max]
                               , c <- [b..max] , a*a + b*b == c*c]
      
      length $ triangles 100 -- => 52
      
      triangles 100
      -- =>
      {-
      [(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(9,40,41),
      (10,24,26),(11,60,61),(12,16,20),(12,35,37),(13,84,85),(14,48,50),
      (15,20,25),(15,36,39),(16,30,34),(16,63,65),(18,24,30),(18,80,82),
      (20,21,29),(20,48,52),(21,28,35),(21,72,75),(24,32,40),(24,45,51),
      (24,70,74),(25,60,65),(27,36,45),(28,45,53),(28,96,100),(30,40,50),
      (30,72,78),(32,60,68),(33,44,55),(33,56,65),(35,84,91),(36,48,60),
      (36,77,85),(39,52,65),(39,80,89),(40,42,58),(40,75,85),(42,56,70),
      (45,60,75),(48,55,73),(48,64,80),(51,68,85),(54,72,90),(57,76,95),
      (60,63,87),(60,80,100),(65,72,97)]
      -}
      



    • Ruby で内包表記