7つの言語7つの世界 Haskell セルフスタディ1日目

「7つの言語 7つの世界」第8章、Haskell(ハスケル)言語

7つの言語 7つの世界

  • Ruby
  • Io
  • Prolog
  • Scala
  • Erlang
  • Cloijure
  • Haskell

セルフスタディ1日目

allEven

• allEven にはいろいろな書き方がある.何通りの書き方を見つけられるか試してみよ.

リスト内包表記を使ったバージョン

allEven :: [Integer] -> [Integer] allEven list = [x | x <- list, even x]

ひとつしか思いつかなかったみたいね

リストを逆順

• リストを受け取って,同じリスト(の各項の並び)を逆順にして返す関数を書け.

標準のreverse関数があります。reverse関数を自前で書きなさいと考えて、

reverseList :: [t] -> [t] reverseList [] = [] reverseList (h:t) = reverseList t ++ [h]
*Main> reverseList [1, 2] [2,1] *Main> reverseList [[1], [2]] [[2],[1]] *Main> reverseList ["1", "2"] ["2","1"]

black , white , blue , yellow , red

• black , white , blue , yellow , red から 2 色を取った組み合わせを表す 2 要素のタプルをすべて作成する関数を書け.順番は関係ないので,例えば, (black, blue)と (blue, black) はどちらか一方のみを含めるようにすること.

p243の let crew = ["Kirk", "Spock", "McCoy"] のくだりを流用して、

colors :: [String] colors = ["black", "white", "blue", "yellow", "red"] colorPairs :: [(String,String)] colorPairs = [(a, b) | a <- colors, b <- colors, a < b]
*Main> colors ["black","white","blue","yellow","red"] *Main> colorPairs [("black","white"),("black","blue"),("black","yellow"),("black","red"),("white","yellow"),("blue","white"),("blue","yellow"),("blue","red"),("red","white"),("red","yellow")]

12x12の乗算表

•リスト内包表記を用いて,子供が使う乗算表を作れ.この表は, 3 要素のタプルのリストとして表現できる.その場合,各タプルの最初の 2 要素は 1 〜 12 の整数, 3番目の要素は最初の 2 要素を掛け合わせた値となる.

次のリストを作る関数を作ります。

[ (1,1,1),(1,2,2),(1,3,3),,,,(1,12,12), (2,1,2),(2,2,4),(2,3,6),,,,(2,12,24), (12,1,12),(12,2,24),(12,3,36),,,,(12,12,144) ]
mulitiplicationTable = [mulitiplicationRow y | y <- [1 .. 12]] mulitiplicationRow y = [(y, x, x * y) | x <- [1 .. 12]]

さきほどのリストを表示する際に、先頭行に、x = 1, 2,,, 12、各行の先頭列に y = 1, 2,,,12 を表示して、交差するセルには、x * y の結果を表示するようにしてみます。

1 2 3 4 5 6 7 8 9 10 11 12 1 1 2 3 4 5 6 7 8 9 10 11 12 2 2 4 6 8 10 12 14 16 18 20 22 24 3 3 6 9 12 15 18 21 24 27 30 33 36 4 4 8 12 16 20 24 28 32 36 40 44 48 5 5 10 15 20 25 30 35 40 45 50 55 60 6 6 12 18 24 30 36 42 48 54 60 66 72 7 7 14 21 28 35 42 49 56 63 70 77 84 8 8 16 24 32 40 48 56 64 72 80 88 96 9 9 18 27 36 45 54 63 72 81 90 99 108 10 10 20 30 40 50 60 70 80 90 100 110 120 11 11 22 33 44 55 66 77 88 99 110 121 132 12 12 24 36 48 60 72 84 96 108 120 132 144
module Main where main :: IO () main = return () mulitiplicationTable = [mulitiplicationRow y | y <- [1 .. 12]] mulitiplicationRow y = [(y, x, x * y) | x <- [1 .. 12]] printMulticationTalbe :: IO () printMulticationTalbe = do printList (makeHeader mulitiplicationTable) printTable (makeBody mulitiplicationTable) makeHeader (h:t) = do "" : [show x | (y, x, z) <- h] makeBody [] = [] makeBody (h:t) = do let y = [show y | (y, x, z) <- h, x == 1] let cells = [show z | (y, x, z) <- h] let line = y ++ cells line : makeBody t printCell :: String -> IO () printCell x = do putStr x putStr "\t" printList :: [String] -> IO () printList [] = do putStrLn "" printList (h:t) = do printCell h printList t printTable :: [[String]] -> IO () printTable [] = do putStr "" printTable (h:t) = do printList h printTable t

printに手間をかけすぎじゃない?

他の言語のforeach的な書き方がわからなかったみたいよ

地図塗り分け問題

• Haskell を使って,地図塗り分け問題( 4.2 「地図の塗り分け」 ( p. 78 ) )を解いてみよ.

リスト内包表記を使って、隣接する色が違う条件を指定しました。

簡潔に記述できたけど、内部では総当り的な処理をしているのかしら?

module Main where main :: IO () main = return () coloring = do let colors = ["red", "green", "blue"] [(tennessee, mississippi, alabama, georgia, florida) | tennessee <- colors, mississippi <- colors, alabama <- colors, georgia <- colors, florida <- colors, tennessee /= mississippi, tennessee /= alabama, tennessee /= georgia, mississippi /= alabama, alabama /= georgia, alabama /= florida, georgia /= florida ]
*Main> coloring [("red","green","blue","green","red"), ("red","blue","green","blue","red"), ("green","red","blue","red","green"), ("green","blue","red","blue","green"), ("blue","red","green","red","blue"), ("blue","green","red","green","blue")]

おすすめ書籍

Grahaum Hutton (著) ラムダノート 2019

タイトルとURLをコピーしました