@aomoriringo
1986-2005   ◎   Twitter: @aomoriringo             ◎   最近使ってる言語                 ◦ C#             ◎   趣味2005-2011        ◦ M...
◎   いくつかの関数や型、型クラスなどを定義したファイル◎   Haskellのプログラムはモジュールの集合◎   コードをモジュールに分割するとしあわせ    ◦ 再利用性を高める    ◦ 管理・修正しやすくする
◎   モジュールをインポートする◎   標準モジュールを使ってみる    ◦ 標準モジュールでいろいろ作ってみる    ◦ foldl, foldl’    ◦ 連想リスト◎   自分でモジュールを作ってみる
モジュールをインポートする
◎   全てをインポート    import Data.List◎   nub, sortのみをインポート    import Data.List (nub, sort)◎   nub以外の全てをインポート    import Data.Lis...
import qualified Data.Map  ◦ Data.Map.filterのように参照import qualified Data.Map as M  ◦ M.filterのように参照
◎   module Fooにhogeとbarがあるとき宣言                          インポートされるもの 参照の方法import Foo                  hoge, bar   hoge, bar ...
◎   Data.Listをインポートghci> :m + Data.Listghci> :m + Data.List Data.Map Data.Set◎   Data.Listのインポートを解除ghci> :m – Data.List◎  ...
標準モジュールを使ってみる       Data.List       Data.Char        Data.Map
◎   Hackage    ◦ hackage.haskell.org/packages/hackage.html◎   Hoogle    ◦ http://www.haskell.org/hoogle/    ◦ 標準モジュールのソースコ...
◎   単語の個数を調べるghci> :t wordNumswordNums :: String -> [(String,Int)]ghci> wordNums "a haskell learn haskell a a learn good"[...
◎   文字列を空白で区切られた文字列のリストに変換するghci> :t wordswords :: String -> [String]ghci> words “hey these are the words”[“hey”, “these”,...
◎   リストの同じ要素をグループ化するghci> :t groupgroup :: Eq a => [a] -> [[a]]ghci> group [1,1,1,2,2,2,3,3,2,2,5,7][[1,1,1],[2,2,2],[3,3]...
◎   リストを昇順に並べ替えるghci> :t sortsort :: Ord a => [a] -> [a]ghci> sort [5,4,3,7,2,1][1,2,3,4,5,7]ghci> sort [“hoge”, “var”, “v...
文字列を単語に区切って (words)→ソートして (sort)→グループ化して (group)→グループごとに数を数えればできそうですね!
◎   wordNumsの定義wordNums :: String -> [(String,Int)]wordNums = map (¥ws -> (head ws, length ws)) .           group . sort ....
◎   あるリストが別のリストに含まれるかどうかを調べるghci> :t isInisIn :: [a] -> [a] -> Boolghci> “art” `isIn` “party”Trueghci> [1,2] `isIn` [1,3,5...
◎   リストに対してtailを繰り返し適用するghci> :t tailstails :: [a] -> [[a]]ghci> tails “party”[“party”, “arty”, “rty”, “ty”, “y”, “”]ghci>...
◎   2つ目のリストが1つ目のリストで    始まっているかどうかを返すghci> :t isPrefixOfisPrefixOf :: String -> String -> Boolghci> “hawaii” `isPrefixOf` ...
“art” `isPrefixOf` “party”   -- False“art” `isPrefixOf` “arty”    -- True“art” `isPrefixOf` “rty”     -- False“art” `isPre...
◎   リストのうち、述語を満たすものがあるかどうかを返すghci> :t anyany :: (a -> Bool) -> [a] -> Boolghci> any (>4) [1,2,3]Falseghci> any id [False, ...
◎   isInの定義isIn :: (Eq a) => [a] -> [a] -> Boolneedle `isIn` haystack =      any (needle `isPrefixOf`) (tails haystack)nee...
◎   Data.List.isPrefixOf    ◦ 前方一致    ◦ さっき使った◎   Data.List.isSuffixOf    ◦ 後方一致◎   Data.List.isInfixOf    ◦ 中間一致    ◦ さっき...
◎   シーザー暗号    ◦ 平文の各文字を辞書順にn文字シフトして作る
◎   文字<->Unicode変換ghci> :t ordord :: Char -> Intghci> ord ‘a’97ghci> :t chrchr :: Int -> Charghci> chr 97‘a’ghci> map ord ...
◎   指定した文字数分シフトするencode :: Int -> String -> Stringencode offset msg =            map (¥c -> chr $ ord c + offset) msg◎   指...
ghci> encode 3 “hey mark”“kh|#pdun”ghci> decode 3 “kh|#pdun”“hey mark”ghci> decode 3 $ encode 3 “abc”“abc”
◎   各桁の数の合計がnになる最初の自然数をみつけるghci> :t firstTofirstTo :: Int -> Intghci> firstTo 11ghci> firstTo 1349
◎   文字を数に変換するghci> :t digitToIntdigitToInt :: Char -> Intghci> digitToInt ‘2’2ghci> digitToInt ‘F’15ghci> digitToInt ‘z’**...
◎   各桁の数の和を返すdigitSum :: Int -> IntdigitSum = sum . map digitToInt . showghci> digitSum 303ghci> digitSum 123410
ghci> :t findfind :: (a -> Bool) -> [a] -> Maybe aghci> find (>4) [3,4,5,6,7]         Nothing | Just aJust 5ghci> find odd...
◎   firstToの定義firstTo :: Int -> Maybe IntfirstTo n =      find (¥x -> digitSum x == n) [1..]ghci> firstTo 27Just 999ghci> ...
foldl, foldl’
ghci> foldl (+) 0 [1..2000000]2000001000000 ◦ 遅い ◦ サイズ、環境によってはスタックオーバーフローghci> Data.List.foldl’ (+) 0 [1..2000000]20000010...
foldl (+) 0 [1,2,3] =foldl (+) (0 + 1) [2,3] =foldl (+) ((0 + 1) + 2) [3] =foldl (+) (((0 + 1) + 2) + 3) [] =((0 + 1) + 2)...
◎   正格な(遅延でない)左畳み込みfoldl’   (+)   0   [1,2,3] =foldl’   (+)   1   [2,3] =foldl’   (+)   3   [3] =foldl’   (+)   6   [] =6
連想リスト
◎   添字として任意の型を使用する配列◎   呼び方はいろいろ    ◦ Map    ◦ Dictionary    ◦ Hash
◎   タプルを連想リストっぽく扱うghci> :t lookuplookup :: Eq a => a -> [(a,b)] -> Maybe bghci> lookup “b” [(“a”,1), (“b”,2), (“c”,3)]Just...
◎   連想リスト(Map)のモジュール    ◦   Data.Map.lookup    ◦   Data.Map.insert    ◦   Data.Map.delete    ◦   Data.Map.size    ◦   etc..
◎ Data.Mapで連想リストを表す型◎ keyとvalueの型を持つghci> let m = Data.Map.fromList [(“foo”,1), (“bar”,2)]ghci> :t mm :: Data.Map.Map [Cha...
ghci> import qualified Data.Map as Map◎   keyで検索するghci> let m = Map.fromList [(“a”,1), (“b”,2)]ghci> Map.lookup “b” mJust ...
◎   valueに関数を適用して新しいMapを作るghci> m2fromList [("a",1),("b",2),("c",3)]ghci> Map.map (^2) m2fromList [("a",1),("b",4),("c",9)...
◎   keyが重複した際の振る舞いを決めるghci> Map.fromList [(1,2),(1,50),(1,10),(2,3)]fromList [(1,10),(2,3)]ghci> Map.fromListWith (+) [(1,...
モジュールを作る
◎   先頭にモジュール宣言を書く    -- Foo.hs    module Foo where    ◦ モジュール名とファイル名は同じにしなければならない◎   モジュールの中身を    ◦ 全て公開したい(エクスポート)      m...
◎   test1/Nums.hs      module Nums where     double x = x + x     quadruple x = double x + double x◎   test1/Main.hs      ...
◎   test1/Nums.hs      module Nums (double) where     double x = x + x     quadruple x = double x + double x◎   test1/Main...
◎   モジュールは階層構造を持つことが可能◎   階層構造は「A.B.C」のようにドット「.」で表す◎   A.B.Cというモジュール名にした場合は、    A/B/C.hsというファイル構成にする
◎   test1/Figure/Sphere.hs      module Figure.Sphere where      Area radius = 4 * pi * (radius ^ 2)◎   test1/Figure/Rectan...
◎   インポート, エクスポートはどちらも範囲を限定できる◎   標準モジュールを調べる, 使う, 理解するサイクルを    身につけたい◎   「こんなのないかな?」と思ったらHoogleとかで探す◎   モジュールのエクスポートを気にして...
Upcoming SlideShare
Loading in...5
×

すごいHaskell楽しく学ぼう 第6章

5,095

Published on

スタートHaskell2で発表

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,095
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
28
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

すごいHaskell楽しく学ぼう 第6章

  1. 1. @aomoriringo
  2. 2. 1986-2005 ◎ Twitter: @aomoriringo ◎ 最近使ってる言語 ◦ C# ◎ 趣味2005-2011 ◦ Mathematica2011- ◎ Haskell歴 ◦ 2ヶ月未満
  3. 3. ◎ いくつかの関数や型、型クラスなどを定義したファイル◎ Haskellのプログラムはモジュールの集合◎ コードをモジュールに分割するとしあわせ ◦ 再利用性を高める ◦ 管理・修正しやすくする
  4. 4. ◎ モジュールをインポートする◎ 標準モジュールを使ってみる ◦ 標準モジュールでいろいろ作ってみる ◦ foldl, foldl’ ◦ 連想リスト◎ 自分でモジュールを作ってみる
  5. 5. モジュールをインポートする
  6. 6. ◎ 全てをインポート import Data.List◎ nub, sortのみをインポート import Data.List (nub, sort)◎ nub以外の全てをインポート import Data.List hiding (nub)
  7. 7. import qualified Data.Map ◦ Data.Map.filterのように参照import qualified Data.Map as M ◦ M.filterのように参照
  8. 8. ◎ module Fooにhogeとbarがあるとき宣言 インポートされるもの 参照の方法import Foo hoge, bar hoge, bar Foo.hoge, Foo.barimport Foo () (なし)import Foo (hoge) hoge hoge, Foo.hogeimport Foo hiding (hoge) bar bar, Foo.barimport qualified Foo hoge, bar Foo.hoge, Foo.barimport Foo as F hoge, bar hoge, bar F.hoge, F.barimport qualified Foo as F hoge, bar F.hoge, F.bar
  9. 9. ◎ Data.Listをインポートghci> :m + Data.Listghci> :m + Data.List Data.Map Data.Set◎ Data.Listのインポートを解除ghci> :m – Data.List◎ importも使用可能ghci> import Data.List (nub, sort)ghci> import qualified Data.Map as M hiding (foldl)
  10. 10. 標準モジュールを使ってみる Data.List Data.Char Data.Map
  11. 11. ◎ Hackage ◦ hackage.haskell.org/packages/hackage.html◎ Hoogle ◦ http://www.haskell.org/hoogle/ ◦ 標準モジュールのソースコードが見れます◎ Hayoo! ◦ http://holumbus.fh-wedel.de/hayoo/hayoo.html
  12. 12. ◎ 単語の個数を調べるghci> :t wordNumswordNums :: String -> [(String,Int)]ghci> wordNums "a haskell learn haskell a a learn good"[("a",3),("good",1),("haskell",2),("learn",2)]
  13. 13. ◎ 文字列を空白で区切られた文字列のリストに変換するghci> :t wordswords :: String -> [String]ghci> words “hey these are the words”[“hey”, “these”, “are”, “the”, “words”]ghci> words “hey these are the words”[“hey”, “these”, “are”, “the”, “words”]
  14. 14. ◎ リストの同じ要素をグループ化するghci> :t groupgroup :: Eq a => [a] -> [[a]]ghci> group [1,1,1,2,2,2,3,3,2,2,5,7][[1,1,1],[2,2,2],[3,3],[2,2],[5],[7]]ghci> group [“hoge”, “var”, “var”, “hoge”, “hoge”][[“hoge”], [“var”, “var”], [“hoge”, “hoge”]]
  15. 15. ◎ リストを昇順に並べ替えるghci> :t sortsort :: Ord a => [a] -> [a]ghci> sort [5,4,3,7,2,1][1,2,3,4,5,7]ghci> sort [“hoge”, “var”, “var”, “hoge”, “hoge”][“hoge”, “hoge”, “hoge”, “var”, “var”]
  16. 16. 文字列を単語に区切って (words)→ソートして (sort)→グループ化して (group)→グループごとに数を数えればできそうですね!
  17. 17. ◎ wordNumsの定義wordNums :: String -> [(String,Int)]wordNums = map (¥ws -> (head ws, length ws)) . group . sort . wordsghci> wordNums “a b c b c”[("a",1),(“b",2),(“c",2)]ghci> wordNums “”[]
  18. 18. ◎ あるリストが別のリストに含まれるかどうかを調べるghci> :t isInisIn :: [a] -> [a] -> Boolghci> “art” `isIn` “party”Trueghci> [1,2] `isIn` [1,3,5]False
  19. 19. ◎ リストに対してtailを繰り返し適用するghci> :t tailstails :: [a] -> [[a]]ghci> tails “party”[“party”, “arty”, “rty”, “ty”, “y”, “”]ghci> tails [1,2,3][[1,2,3], [2,3], [3], []]
  20. 20. ◎ 2つ目のリストが1つ目のリストで 始まっているかどうかを返すghci> :t isPrefixOfisPrefixOf :: String -> String -> Boolghci> “hawaii” `isPrefixOf` “hawaii joe”Trueghci> “haha” `isPrefixOf` “ha”Falseghci> “ha” `isPrefixOf` “haha”True
  21. 21. “art” `isPrefixOf` “party” -- False“art” `isPrefixOf` “arty” -- True“art” `isPrefixOf` “rty” -- False“art” `isPrefixOf` “ty” -- False“art” `isPrefixOf` “y” -- False
  22. 22. ◎ リストのうち、述語を満たすものがあるかどうかを返すghci> :t anyany :: (a -> Bool) -> [a] -> Boolghci> any (>4) [1,2,3]Falseghci> any id [False, False, True]True
  23. 23. ◎ isInの定義isIn :: (Eq a) => [a] -> [a] -> Boolneedle `isIn` haystack = any (needle `isPrefixOf`) (tails haystack)needle: 針。見つけたいリストhaystack: 干し草の山。検索対象のリスト
  24. 24. ◎ Data.List.isPrefixOf ◦ 前方一致 ◦ さっき使った◎ Data.List.isSuffixOf ◦ 後方一致◎ Data.List.isInfixOf ◦ 中間一致 ◦ さっき作った(isIn)
  25. 25. ◎ シーザー暗号 ◦ 平文の各文字を辞書順にn文字シフトして作る
  26. 26. ◎ 文字<->Unicode変換ghci> :t ordord :: Char -> Intghci> ord ‘a’97ghci> :t chrchr :: Int -> Charghci> chr 97‘a’ghci> map ord “abcdefgh”[97,98,99,100,101,102,103,104]
  27. 27. ◎ 指定した文字数分シフトするencode :: Int -> String -> Stringencode offset msg = map (¥c -> chr $ ord c + offset) msg◎ 指定した文字数分逆にシフトするdecode :: Int -> String -> Stringdecode shift msg = encode (negate shift) msg
  28. 28. ghci> encode 3 “hey mark”“kh|#pdun”ghci> decode 3 “kh|#pdun”“hey mark”ghci> decode 3 $ encode 3 “abc”“abc”
  29. 29. ◎ 各桁の数の合計がnになる最初の自然数をみつけるghci> :t firstTofirstTo :: Int -> Intghci> firstTo 11ghci> firstTo 1349
  30. 30. ◎ 文字を数に変換するghci> :t digitToIntdigitToInt :: Char -> Intghci> digitToInt ‘2’2ghci> digitToInt ‘F’15ghci> digitToInt ‘z’*** Exception: Char.digitToInt: not a digit z
  31. 31. ◎ 各桁の数の和を返すdigitSum :: Int -> IntdigitSum = sum . map digitToInt . showghci> digitSum 303ghci> digitSum 123410
  32. 32. ghci> :t findfind :: (a -> Bool) -> [a] -> Maybe aghci> find (>4) [3,4,5,6,7] Nothing | Just aJust 5ghci> find odd [2,4,6,8,9]Just 9ghci> find (==‘z’) “haskell”Nothing
  33. 33. ◎ firstToの定義firstTo :: Int -> Maybe IntfirstTo n = find (¥x -> digitSum x == n) [1..]ghci> firstTo 27Just 999ghci> firstTo 40Just 49999
  34. 34. foldl, foldl’
  35. 35. ghci> foldl (+) 0 [1..2000000]2000001000000 ◦ 遅い ◦ サイズ、環境によってはスタックオーバーフローghci> Data.List.foldl’ (+) 0 [1..2000000]2000001000000 ◦ foldlより速い ◦ オーバーフローしない
  36. 36. foldl (+) 0 [1,2,3] =foldl (+) (0 + 1) [2,3] =foldl (+) ((0 + 1) + 2) [3] =foldl (+) (((0 + 1) + 2) + 3) [] =((0 + 1) + 2) + 3 =(1 + 2) + 3 =3 + 3 =6
  37. 37. ◎ 正格な(遅延でない)左畳み込みfoldl’ (+) 0 [1,2,3] =foldl’ (+) 1 [2,3] =foldl’ (+) 3 [3] =foldl’ (+) 6 [] =6
  38. 38. 連想リスト
  39. 39. ◎ 添字として任意の型を使用する配列◎ 呼び方はいろいろ ◦ Map ◦ Dictionary ◦ Hash
  40. 40. ◎ タプルを連想リストっぽく扱うghci> :t lookuplookup :: Eq a => a -> [(a,b)] -> Maybe bghci> lookup “b” [(“a”,1), (“b”,2), (“c”,3)]Just 2ghci> lookup “k” [(“a”,1), (“b”,2), (“c”,3)]Nothing
  41. 41. ◎ 連想リスト(Map)のモジュール ◦ Data.Map.lookup ◦ Data.Map.insert ◦ Data.Map.delete ◦ Data.Map.size ◦ etc..
  42. 42. ◎ Data.Mapで連想リストを表す型◎ keyとvalueの型を持つghci> let m = Data.Map.fromList [(“foo”,1), (“bar”,2)]ghci> :t mm :: Data.Map.Map [Char] Integerghci> let m2 = Data.Map.fromList [(‘a’, True), (‘b’, False)]ghci> :t m2m2 :: Data.Map.Map Char Bool
  43. 43. ghci> import qualified Data.Map as Map◎ keyで検索するghci> let m = Map.fromList [(“a”,1), (“b”,2)]ghci> Map.lookup “b” mJust 2ghci> Map.lookup “c” mNothing◎ key=“c”, value=3の要素を挿入するghci> let m2 = Map.insert “c” 3 mghci> Map.lookup “c” m2Just 3ghci> Map.size m23
  44. 44. ◎ valueに関数を適用して新しいMapを作るghci> m2fromList [("a",1),("b",2),("c",3)]ghci> Map.map (^2) m2fromList [("a",1),("b",4),("c",9)]ghci> Map.map show m2fromList [(“a”,”1”), (“b”,”2”), (“c”, “3”)]
  45. 45. ◎ keyが重複した際の振る舞いを決めるghci> Map.fromList [(1,2),(1,50),(1,10),(2,3)]fromList [(1,10),(2,3)]ghci> Map.fromListWith (+) [(1,2),(1,50),(1,10),(2,3)]fromList [(1,62),(2,3)]ghci> Map.fromListWith max [(1,2),(1,50),(1,10),(2,3)]fromList [(1,50),(2,3)]
  46. 46. モジュールを作る
  47. 47. ◎ 先頭にモジュール宣言を書く -- Foo.hs module Foo where ◦ モジュール名とファイル名は同じにしなければならない◎ モジュールの中身を ◦ 全て公開したい(エクスポート) module Foo where ◦ 一部だけ公開したい ◦ module Foo (hoge, var) where
  48. 48. ◎ test1/Nums.hs module Nums where double x = x + x quadruple x = double x + double x◎ test1/Main.hs import Nums double2 = Nums.double 2 quadruple4 = Nums.quadruple 4
  49. 49. ◎ test1/Nums.hs module Nums (double) where double x = x + x quadruple x = double x + double x◎ test1/Main.hs import Nums double2 = Nums.double 2 -- OK quadruple4 = Nums.quadruple 4 -- コンパイルエラー
  50. 50. ◎ モジュールは階層構造を持つことが可能◎ 階層構造は「A.B.C」のようにドット「.」で表す◎ A.B.Cというモジュール名にした場合は、 A/B/C.hsというファイル構成にする
  51. 51. ◎ test1/Figure/Sphere.hs module Figure.Sphere where Area radius = 4 * pi * (radius ^ 2)◎ test1/Figure/Rectangle.hs module Figure.Rectangle where Area width height = width * height◎ test1/Main.hs import qualified Figure.Sphere as Sphere import qualified Figure.Rectangle as Rect sphereArea = Sphere.Area rectArea = Rect.Area
  52. 52. ◎ インポート, エクスポートはどちらも範囲を限定できる◎ 標準モジュールを調べる, 使う, 理解するサイクルを 身につけたい◎ 「こんなのないかな?」と思ったらHoogleとかで探す◎ モジュールのエクスポートを気にしてきれいなコードを 書きたいですね
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×