すごいHaskell楽しく学ぼう 第6章
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

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

  • 5,320 views
Uploaded on

スタートHaskell2で発表

スタートHaskell2で発表

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
5,320
On Slideshare
3,510
From Embeds
1,810
Number of Embeds
9

Actions

Shares
Downloads
27
Comments
0
Likes
2

Embeds 1,810

http://control.blog.fc2.com 1,070
http://aomoriringo.hateblo.jp 515
http://makopi23.blog.fc2.com 203
https://si0.twimg.com 9
https://twimg0-a.akamaihd.net 7
http://webcache.googleusercontent.com 3
http://a0.twimg.com 1
https://abs.twimg.com 1
http://feedly.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. @aomoriringo
  • 2. 1986-2005 ◎ Twitter: @aomoriringo ◎ 最近使ってる言語 ◦ C# ◎ 趣味2005-2011 ◦ Mathematica2011- ◎ Haskell歴 ◦ 2ヶ月未満
  • 3. ◎ いくつかの関数や型、型クラスなどを定義したファイル◎ Haskellのプログラムはモジュールの集合◎ コードをモジュールに分割するとしあわせ ◦ 再利用性を高める ◦ 管理・修正しやすくする
  • 4. ◎ モジュールをインポートする◎ 標準モジュールを使ってみる ◦ 標準モジュールでいろいろ作ってみる ◦ foldl, foldl’ ◦ 連想リスト◎ 自分でモジュールを作ってみる
  • 5. モジュールをインポートする
  • 6. ◎ 全てをインポート import Data.List◎ nub, sortのみをインポート import Data.List (nub, sort)◎ nub以外の全てをインポート import Data.List hiding (nub)
  • 7. import qualified Data.Map ◦ Data.Map.filterのように参照import qualified Data.Map as M ◦ M.filterのように参照
  • 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. ◎ 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. 標準モジュールを使ってみる Data.List Data.Char Data.Map
  • 11. ◎ Hackage ◦ hackage.haskell.org/packages/hackage.html◎ Hoogle ◦ http://www.haskell.org/hoogle/ ◦ 標準モジュールのソースコードが見れます◎ Hayoo! ◦ http://holumbus.fh-wedel.de/hayoo/hayoo.html
  • 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. ◎ 文字列を空白で区切られた文字列のリストに変換する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. ◎ リストの同じ要素をグループ化する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. ◎ リストを昇順に並べ替える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. 文字列を単語に区切って (words)→ソートして (sort)→グループ化して (group)→グループごとに数を数えればできそうですね!
  • 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. ◎ あるリストが別のリストに含まれるかどうかを調べるghci> :t isInisIn :: [a] -> [a] -> Boolghci> “art” `isIn` “party”Trueghci> [1,2] `isIn` [1,3,5]False
  • 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. ◎ 2つ目のリストが1つ目のリストで 始まっているかどうかを返すghci> :t isPrefixOfisPrefixOf :: String -> String -> Boolghci> “hawaii” `isPrefixOf` “hawaii joe”Trueghci> “haha” `isPrefixOf` “ha”Falseghci> “ha” `isPrefixOf` “haha”True
  • 21. “art” `isPrefixOf` “party” -- False“art” `isPrefixOf` “arty” -- True“art” `isPrefixOf` “rty” -- False“art” `isPrefixOf` “ty” -- False“art” `isPrefixOf` “y” -- False
  • 22. ◎ リストのうち、述語を満たすものがあるかどうかを返すghci> :t anyany :: (a -> Bool) -> [a] -> Boolghci> any (>4) [1,2,3]Falseghci> any id [False, False, True]True
  • 23. ◎ isInの定義isIn :: (Eq a) => [a] -> [a] -> Boolneedle `isIn` haystack = any (needle `isPrefixOf`) (tails haystack)needle: 針。見つけたいリストhaystack: 干し草の山。検索対象のリスト
  • 24. ◎ Data.List.isPrefixOf ◦ 前方一致 ◦ さっき使った◎ Data.List.isSuffixOf ◦ 後方一致◎ Data.List.isInfixOf ◦ 中間一致 ◦ さっき作った(isIn)
  • 25. ◎ シーザー暗号 ◦ 平文の各文字を辞書順にn文字シフトして作る
  • 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. ◎ 指定した文字数分シフトするencode :: Int -> String -> Stringencode offset msg = map (¥c -> chr $ ord c + offset) msg◎ 指定した文字数分逆にシフトするdecode :: Int -> String -> Stringdecode shift msg = encode (negate shift) msg
  • 28. ghci> encode 3 “hey mark”“kh|#pdun”ghci> decode 3 “kh|#pdun”“hey mark”ghci> decode 3 $ encode 3 “abc”“abc”
  • 29. ◎ 各桁の数の合計がnになる最初の自然数をみつけるghci> :t firstTofirstTo :: Int -> Intghci> firstTo 11ghci> firstTo 1349
  • 30. ◎ 文字を数に変換するghci> :t digitToIntdigitToInt :: Char -> Intghci> digitToInt ‘2’2ghci> digitToInt ‘F’15ghci> digitToInt ‘z’*** Exception: Char.digitToInt: not a digit z
  • 31. ◎ 各桁の数の和を返すdigitSum :: Int -> IntdigitSum = sum . map digitToInt . showghci> digitSum 303ghci> digitSum 123410
  • 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. ◎ firstToの定義firstTo :: Int -> Maybe IntfirstTo n = find (¥x -> digitSum x == n) [1..]ghci> firstTo 27Just 999ghci> firstTo 40Just 49999
  • 34. foldl, foldl’
  • 35. ghci> foldl (+) 0 [1..2000000]2000001000000 ◦ 遅い ◦ サイズ、環境によってはスタックオーバーフローghci> Data.List.foldl’ (+) 0 [1..2000000]2000001000000 ◦ foldlより速い ◦ オーバーフローしない
  • 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. ◎ 正格な(遅延でない)左畳み込みfoldl’ (+) 0 [1,2,3] =foldl’ (+) 1 [2,3] =foldl’ (+) 3 [3] =foldl’ (+) 6 [] =6
  • 38. 連想リスト
  • 39. ◎ 添字として任意の型を使用する配列◎ 呼び方はいろいろ ◦ Map ◦ Dictionary ◦ Hash
  • 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. ◎ 連想リスト(Map)のモジュール ◦ Data.Map.lookup ◦ Data.Map.insert ◦ Data.Map.delete ◦ Data.Map.size ◦ etc..
  • 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. 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. ◎ 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. ◎ 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. モジュールを作る
  • 47. ◎ 先頭にモジュール宣言を書く -- Foo.hs module Foo where ◦ モジュール名とファイル名は同じにしなければならない◎ モジュールの中身を ◦ 全て公開したい(エクスポート) module Foo where ◦ 一部だけ公開したい ◦ module Foo (hoge, var) where
  • 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. ◎ 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. ◎ モジュールは階層構造を持つことが可能◎ 階層構造は「A.B.C」のようにドット「.」で表す◎ A.B.Cというモジュール名にした場合は、 A/B/C.hsというファイル構成にする
  • 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. ◎ インポート, エクスポートはどちらも範囲を限定できる◎ 標準モジュールを調べる, 使う, 理解するサイクルを 身につけたい◎ 「こんなのないかな?」と思ったらHoogleとかで探す◎ モジュールのエクスポートを気にしてきれいなコードを 書きたいですね