すごいHaskellたのしく学ぼう!   6. モジュール                 伊勢  シン / 伊藤  伸裕すごいHaskell読書会 in ⼤大阪#4 @ Fenrir Inc.
⾃自⼰己紹介•  伊勢  シン / 伊藤  伸裕  –  @iseebi / id:iseebi•  スマートフォンアプリ作ってます。  –  学⽣生時代は機械CADとか構造⼯工学のようなこととか  –  趣味が転じてこんなことに•  関数型⾔...
この資料料について•  今回は、途中で資料料に書き込んで   完成させていくスタイルを取りました。•  ⻘青い字で書いた部分は、当⽇日書き加えたところ   です。また、タイトル部分が⻘青い場合は、そのペー   ジ⾃自体を当⽇日加えています。• ...
モジュール•  関数、型、型クラスを定義したファイル•  好きなだけ定義して、   好きなだけ公開(エクスポート)できる。•  再利利⽤用のため、管理理のため。•  他の⾔言語でもよくありますよね。 –  どこいっても疎結合にしておくのは⼤大事...
ところで•  ghci 起動した時に出てくるこれ  $ ghci  GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help  Loading package ghc-prim ....
Haskell の標準モジュール•  ⽬目的に応じていろいろ分割されてる•  デフォルトで  Prelude モジュールがロードされてる。  –  5章までに出てきた関数などはすべてこのモジュールに     ⼊入っているもの。•  Hoogle...
とりあえず動かす•  import ⽂文を使う。  –  GHCi  では  :m  を使うと本⽂文にあるけど、     訳注に今は import 書けるってあるので、     使うのは import で合わせてしまったほうが     ⾯面倒少...
import のバリエーション•  特定の関数だけ取り込む Prelude> import Data.List (nub, sort) •  特定の関数以外取り込む Prelude> import Data.List hiding (nub) ...
衝突したら?•  上書きされることはなく、エラーになる。   –  当然っちゃ当然   –  実⾏行行されるまでは発覚しない…Prelude> import Data.MapPrelude Data.Map> null "a"<interact...
標準モジュールの関数で問題を解く (1)•  ⽂文字列列から単語のリスト  (Data.List.words) Prelude Data.List> words "hey thease are the words in this sentenc...
再エクスポートmodule A (   words              スコープにあるものがエクスポートされる)whereimport Data.Listmodule A (                   モジュールにあるものが⼀一...
3つあわせて -> 単語を数える•  こういう関数ができます。 -> work01.hs  *Main> wordNums "wa wa wee wa wa wa"  [("wa",5),("wee",1)]•  関数合成を有効に使って、みやす...
標準モジュールの関数で問題を解く  (2)•  tails   –  tailを繰り返し実⾏行行•  isPrefixOf   –  2つめのリストが1つめのリストではじまってるかどうか•  any
3つあわせて -> リストの中にリストは含まれる?•  こういう関数ができます。 -> work02.hs  *Main> "art" `isIn` "party"  True•  ちなみに同様の関数は、   Data.List に  isIn...
標準モジュールの関数で問題を解く  (3)•  Data.Char モジュール•  ord   –  Char を受け取り、⽂文字コード数値を返す•  chr   –  数値を受け取り、対応する Char  を返す
2つあわせて -> シーザー暗号•  こういう関数ができます。 -> work03.hs  *Main> encode 4 "Sleipnir"  "Wpimtrmv"  *Main> decode 4 "Wpimtrmv"  "Sleipni...
GHCi便便利利オプション•  :set +t   –  評価したものの型が⾃自動で出⼒力力される•  :set +s   –  実⾏行行時間、消費メモリが⾃自動で出⼒力力される•  ~/.ghci に書いておくといい         $ ca...
標準モジュールの関数で問題を解く  (4)•  左畳込み… –  実は理理解しきれてなくて…
標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char)    •  ⼊入⼒力力されたCharを数字として読んで、数値で返す...
標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char)    •  ⼊入⼒力力されたCharを数字として読んで、数値で返す...
標準モジュールの関数で問題を解く  (5)•  次に、この関数を使って、   find (Data.List) で探す。        Prelude Data.List> :t find        find :: (a -> Bool) ...
Maybeの値を使おうとすると…*Main Data.List> firstTo40Just 49999it :: Maybe Int               Maybe だからそのまま⼊入らない(0.01 secs, 1581784 by...
Maybeの値を使うには•  Data.Maybe.fromJustを使えばいい*Main Data.List> import Data.Maybe(0.00 secs, 2109848 bytes)*Main Data.List Data.M...
キーから値へのマッピング•  連想リスト  まずは⾃自分でやってみる –  work05.hs•  ただ、  Data.Map を使ったほうがはるかに⾼高速。
Mapの基本•  前述のとおり  Data.Map は   かなりの勢いでぶつかる名前持ってるので、   修飾付きインポートする。             import qualified Data.Map as Map •  fromList...
Mapの基本•  Map.lookup  –  抽出•  Map.insert  –  挿⼊入•  Map.size  –  ⻑⾧長さ•  Map.map  –  Map (値にかかる)
値の重複を許す場合•  Map.fromList では、同じキーがあると   その値は失われる。•  Map.fromListWith を使うと、   キーの重複を許すが、重複した時にどうするかを   確認する。 –  work07.hs
モジュールを作る•  ファイル名とモジュールの名前は⼀一致させる。•  ファイルの先頭に、下記のように記述      module Geometry      ( sphereVolume      , sphereArea      , cu...
モジュールを作る•  Data.Map  とかと同じように、階層を切切りたい場   合は –  フォルダを作成する (Geometry/Sphere.hs) –  module の宣⾔言を、階層付きにする    (module Geometry...
Upcoming SlideShare
Loading in …5
×

すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」

1,770 views

Published on

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

No Downloads
Views
Total views
1,770
On SlideShare
0
From Embeds
0
Number of Embeds
683
Actions
Shares
0
Downloads
4
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」

  1. 1. すごいHaskellたのしく学ぼう! 6. モジュール 伊勢  シン / 伊藤  伸裕すごいHaskell読書会 in ⼤大阪#4 @ Fenrir Inc.
  2. 2. ⾃自⼰己紹介•  伊勢  シン / 伊藤  伸裕 –  @iseebi / id:iseebi•  スマートフォンアプリ作ってます。 –  学⽣生時代は機械CADとか構造⼯工学のようなこととか –  趣味が転じてこんなことに•  関数型⾔言語に触れるのはこの読書会がはじめて –  趣味で C# と Ruby –  仕事で Objective-C + Java、転職前は  PHPer。 –  そろそろ落落第しそう
  3. 3. この資料料について•  今回は、途中で資料料に書き込んで 完成させていくスタイルを取りました。•  ⻘青い字で書いた部分は、当⽇日書き加えたところ です。また、タイトル部分が⻘青い場合は、そのペー ジ⾃自体を当⽇日加えています。•  また、⽂文中にファイル名が書いてある部分は、 https://gist.github.com/4509540  にあります。
  4. 4. モジュール•  関数、型、型クラスを定義したファイル•  好きなだけ定義して、 好きなだけ公開(エクスポート)できる。•  再利利⽤用のため、管理理のため。•  他の⾔言語でもよくありますよね。 –  どこいっても疎結合にしておくのは⼤大事•  そういえば、ghciの:loadにもこう書いてあった。 :load [*]<module> ... load module(s) and their dependents
  5. 5. ところで•  ghci 起動した時に出てくるこれ $ ghci GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> •  package って? –  調べたらgemとかと同じパッケージマネージャが あるらしい。(cabal) –  Module の集合が Package であってる? •  厳密にはそうではない。バイナリが含まれることもある。 •  今⽇日の範囲ではその理理解でもOK
  6. 6. Haskell の標準モジュール•  ⽬目的に応じていろいろ分割されてる•  デフォルトで  Prelude モジュールがロードされてる。 –  5章までに出てきた関数などはすべてこのモジュールに ⼊入っているもの。•  Hoogle 使おう
  7. 7. とりあえず動かす•  import ⽂文を使う。 –  GHCi  では  :m  を使うと本⽂文にあるけど、 訳注に今は import 書けるってあるので、 使うのは import で合わせてしまったほうが ⾯面倒少なさそう? Prelude> import Data.List Prelude Data.List> •  :m と :load の違いは? –  :load は、ファイルからしか読めないけど、 :m は、ファイルからは読めない (あらかじめインストールされてるもののみ) –  importはどっちでもOK
  8. 8. import のバリエーション•  特定の関数だけ取り込む Prelude> import Data.List (nub, sort) •  特定の関数以外取り込む Prelude> import Data.List hiding (nub) •  修飾付きインポート (名前衝突するときに) Prelude> import qualified Data.Map 使うとき Data.Map.filter Prelude> import qualified Data.Map as M 使うとき M.filter※関数合成でも . を使うけど、   qualifiedされてて、スペースを開けずに使った場合は、   インポートされた関数とみなす。
  9. 9. 衝突したら?•  上書きされることはなく、エラーになる。 –  当然っちゃ当然 –  実⾏行行されるまでは発覚しない…Prelude> import Data.MapPrelude Data.Map> null "a"<interactive>:1:1: Ambiguous occurrence `null It could refer to either `Prelude.null, imported from Prelude or `Data.Map.null, imported from Data.Map
  10. 10. 標準モジュールの関数で問題を解く (1)•  ⽂文字列列から単語のリスト  (Data.List.words) Prelude Data.List> words "hey thease are the words in this sentence” Prelude Data.List> words "hey thease are the words in this sentence" ※words は  Prelude が再エクスポートしてるので、import せずとも使える  (importしたものをそのまま再度度エクスポートすることができ、この場合は衝突しない)•  グループ化する (Data.List.group) Prelude Data.List> group [1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7] Prelude Data.List> group ["boom","bip","bip","boom","boom”]•  ソートする (Data.List.sort) Prelude Data.List> sort [5,4,3,7,2,1] Prelude Data.List> sort ["boom","bip","bip","boom","boom”]
  11. 11. 再エクスポートmodule A ( words スコープにあるものがエクスポートされる)whereimport Data.Listmodule A ( モジュールにあるものが⼀一括で module Data.List 再エクスポートされる)whereimport Data.List Q. hiding つかえたら便便利利なんだけど? A. 書けないです
  12. 12. 3つあわせて -> 単語を数える•  こういう関数ができます。 -> work01.hs *Main> wordNums "wa wa wee wa wa wa" [("wa",5),("wee",1)]•  関数合成を有効に使って、みやすく。•  ※全く関係ないけど :edit 便便利利すね。
  13. 13. 標準モジュールの関数で問題を解く  (2)•  tails –  tailを繰り返し実⾏行行•  isPrefixOf –  2つめのリストが1つめのリストではじまってるかどうか•  any
  14. 14. 3つあわせて -> リストの中にリストは含まれる?•  こういう関数ができます。 -> work02.hs *Main> "art" `isIn` "party" True•  ちなみに同様の関数は、 Data.List に  isInfixOf とい名前で定義されてい る。
  15. 15. 標準モジュールの関数で問題を解く  (3)•  Data.Char モジュール•  ord –  Char を受け取り、⽂文字コード数値を返す•  chr –  数値を受け取り、対応する Char  を返す
  16. 16. 2つあわせて -> シーザー暗号•  こういう関数ができます。 -> work03.hs *Main> encode 4 "Sleipnir" "Wpimtrmv" *Main> decode 4 "Wpimtrmv" "Sleipnir"•  decodeをつくるときは、encodeを再利利⽤用してる。•  it を使うと、前に評価した値を使える –  GHCi に限る
  17. 17. GHCi便便利利オプション•  :set +t –  評価したものの型が⾃自動で出⼒力力される•  :set +s –  実⾏行行時間、消費メモリが⾃自動で出⼒力力される•  ~/.ghci に書いておくといい $ cat ~/.ghci コマンドなんでもかけるので、 :set +t +s パーミッション注意 $ chmod 600 ~/.ghci•  http://www.kotha.net/ghcguide_ja/latest/ ghci.html
  18. 18. 標準モジュールの関数で問題を解く  (4)•  左畳込み… –  実は理理解しきれてなくて…
  19. 19. 標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char) •  ⼊入⼒力力されたCharを数字として読んで、数値で返す。 –  これと、show の組み合わせで作る。
  20. 20. 標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char) •  ⼊入⼒力力されたCharを数字として読んで、数値で返す。 –  これと、show の組み合わせで作る。
  21. 21. 標準モジュールの関数で問題を解く  (5)•  次に、この関数を使って、 find (Data.List) で探す。 Prelude Data.List> :t find find :: (a -> Bool) -> [a] -> Maybe a•  Maybe a 失敗することがあるという値。 ⾃自分で作るときは、Just を使う。
  22. 22. Maybeの値を使おうとすると…*Main Data.List> firstTo40Just 49999it :: Maybe Int Maybe だからそのまま⼊入らない(0.01 secs, 1581784 bytes)*Main Data.List> digitSum it<interactive>:1:10: Couldnt match expected type `Int with actual type `MaybeInt In the first argument of `digitSum, namely `it In the expression: digitSum it In an equation for `it: it = digitSum it(0.00 secs, 1588312 bytes)
  23. 23. Maybeの値を使うには•  Data.Maybe.fromJustを使えばいい*Main Data.List> import Data.Maybe(0.00 secs, 2109848 bytes)*Main Data.List Data.Maybe> firstTo40Just 49999it :: Maybe Int(0.01 secs, 2115376 bytes)*Main Data.List Data.Maybe> digitSum $ fromJust it40it :: Int(0.01 secs, 2119672 bytes)
  24. 24. キーから値へのマッピング•  連想リスト  まずは⾃自分でやってみる –  work05.hs•  ただ、  Data.Map を使ったほうがはるかに⾼高速。
  25. 25. Mapの基本•  前述のとおり  Data.Map は かなりの勢いでぶつかる名前持ってるので、 修飾付きインポートする。 import qualified Data.Map as Map •  fromList に、さっきやったみたいな 連想リストを渡すと、Mapになる。Prelude Data.Map> Map.fromList [(3,"shoes"),(4,"trees"),(9,"bees")]fromList [(3,"shoes"),(4,"trees"),(9,"bees")]•  これを使って書きなおしてみる。 –  work06.hs
  26. 26. Mapの基本•  Map.lookup –  抽出•  Map.insert –  挿⼊入•  Map.size –  ⻑⾧長さ•  Map.map –  Map (値にかかる)
  27. 27. 値の重複を許す場合•  Map.fromList では、同じキーがあると その値は失われる。•  Map.fromListWith を使うと、 キーの重複を許すが、重複した時にどうするかを 確認する。 –  work07.hs
  28. 28. モジュールを作る•  ファイル名とモジュールの名前は⼀一致させる。•  ファイルの先頭に、下記のように記述 module Geometry ( sphereVolume , sphereArea , cubeVolume 公開するもの , cubeArea , cuboidVolume , cuboidArea ) where -- 実装を書く
  29. 29. モジュールを作る•  Data.Map  とかと同じように、階層を切切りたい場 合は –  フォルダを作成する (Geometry/Sphere.hs) –  module の宣⾔言を、階層付きにする (module Geometry.Sphere)

×