• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
 

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

on

  • 1,511 views

 

Statistics

Views

Total Views
1,511
Views on SlideShare
835
Embed Views
676

Actions

Likes
2
Downloads
2
Comments
0

6 Embeds 676

http://iseebi.hatenablog.com 659
http://flavors.me 9
http://webcache.googleusercontent.com 5
http://translate.googleusercontent.com 1
http://jp.flavors.me 1
https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • すごいHaskellたのしく学ぼう! 6. モジュール 伊勢  シン / 伊藤  伸裕すごいHaskell読書会 in ⼤大阪#4 @ Fenrir Inc.
    • ⾃自⼰己紹介•  伊勢  シン / 伊藤  伸裕 –  @iseebi / id:iseebi•  スマートフォンアプリ作ってます。 –  学⽣生時代は機械CADとか構造⼯工学のようなこととか –  趣味が転じてこんなことに•  関数型⾔言語に触れるのはこの読書会がはじめて –  趣味で C# と Ruby –  仕事で Objective-C + Java、転職前は  PHPer。 –  そろそろ落落第しそう
    • この資料料について•  今回は、途中で資料料に書き込んで 完成させていくスタイルを取りました。•  ⻘青い字で書いた部分は、当⽇日書き加えたところ です。また、タイトル部分が⻘青い場合は、そのペー ジ⾃自体を当⽇日加えています。•  また、⽂文中にファイル名が書いてある部分は、 https://gist.github.com/4509540  にあります。
    • モジュール•  関数、型、型クラスを定義したファイル•  好きなだけ定義して、 好きなだけ公開(エクスポート)できる。•  再利利⽤用のため、管理理のため。•  他の⾔言語でもよくありますよね。 –  どこいっても疎結合にしておくのは⼤大事•  そういえば、ghciの:loadにもこう書いてあった。 :load [*]<module> ... load module(s) and their dependents
    • ところで•  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
    • Haskell の標準モジュール•  ⽬目的に応じていろいろ分割されてる•  デフォルトで  Prelude モジュールがロードされてる。 –  5章までに出てきた関数などはすべてこのモジュールに ⼊入っているもの。•  Hoogle 使おう
    • とりあえず動かす•  import ⽂文を使う。 –  GHCi  では  :m  を使うと本⽂文にあるけど、 訳注に今は import 書けるってあるので、 使うのは import で合わせてしまったほうが ⾯面倒少なさそう? Prelude> import Data.List Prelude Data.List> •  :m と :load の違いは? –  :load は、ファイルからしか読めないけど、 :m は、ファイルからは読めない (あらかじめインストールされてるもののみ) –  importはどっちでもOK
    • 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されてて、スペースを開けずに使った場合は、   インポートされた関数とみなす。
    • 衝突したら?•  上書きされることはなく、エラーになる。 –  当然っちゃ当然 –  実⾏行行されるまでは発覚しない…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
    • 標準モジュールの関数で問題を解く (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”]
    • 再エクスポートmodule A ( words スコープにあるものがエクスポートされる)whereimport Data.Listmodule A ( モジュールにあるものが⼀一括で module Data.List 再エクスポートされる)whereimport Data.List Q. hiding つかえたら便便利利なんだけど? A. 書けないです
    • 3つあわせて -> 単語を数える•  こういう関数ができます。 -> work01.hs *Main> wordNums "wa wa wee wa wa wa" [("wa",5),("wee",1)]•  関数合成を有効に使って、みやすく。•  ※全く関係ないけど :edit 便便利利すね。
    • 標準モジュールの関数で問題を解く  (2)•  tails –  tailを繰り返し実⾏行行•  isPrefixOf –  2つめのリストが1つめのリストではじまってるかどうか•  any
    • 3つあわせて -> リストの中にリストは含まれる?•  こういう関数ができます。 -> work02.hs *Main> "art" `isIn` "party" True•  ちなみに同様の関数は、 Data.List に  isInfixOf とい名前で定義されてい る。
    • 標準モジュールの関数で問題を解く  (3)•  Data.Char モジュール•  ord –  Char を受け取り、⽂文字コード数値を返す•  chr –  数値を受け取り、対応する Char  を返す
    • 2つあわせて -> シーザー暗号•  こういう関数ができます。 -> work03.hs *Main> encode 4 "Sleipnir" "Wpimtrmv" *Main> decode 4 "Wpimtrmv" "Sleipnir"•  decodeをつくるときは、encodeを再利利⽤用してる。•  it を使うと、前に評価した値を使える –  GHCi に限る
    • GHCi便便利利オプション•  :set +t –  評価したものの型が⾃自動で出⼒力力される•  :set +s –  実⾏行行時間、消費メモリが⾃自動で出⼒力力される•  ~/.ghci に書いておくといい $ cat ~/.ghci コマンドなんでもかけるので、 :set +t +s パーミッション注意 $ chmod 600 ~/.ghci•  http://www.kotha.net/ghcguide_ja/latest/ ghci.html
    • 標準モジュールの関数で問題を解く  (4)•  左畳込み… –  実は理理解しきれてなくて…
    • 標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char) •  ⼊入⼒力力されたCharを数字として読んで、数値で返す。 –  これと、show の組み合わせで作る。
    • 標準モジュールの関数で問題を解く  (5)•  各桁の数が40になる最初の整数を探す•  まず、各桁の合計を求める関数を作る –  digitToInt (Data.Char) •  ⼊入⼒力力されたCharを数字として読んで、数値で返す。 –  これと、show の組み合わせで作る。
    • 標準モジュールの関数で問題を解く  (5)•  次に、この関数を使って、 find (Data.List) で探す。 Prelude Data.List> :t find find :: (a -> Bool) -> [a] -> Maybe a•  Maybe a 失敗することがあるという値。 ⾃自分で作るときは、Just を使う。
    • 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)
    • 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)
    • キーから値へのマッピング•  連想リスト  まずは⾃自分でやってみる –  work05.hs•  ただ、  Data.Map を使ったほうがはるかに⾼高速。
    • 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
    • Mapの基本•  Map.lookup –  抽出•  Map.insert –  挿⼊入•  Map.size –  ⻑⾧長さ•  Map.map –  Map (値にかかる)
    • 値の重複を許す場合•  Map.fromList では、同じキーがあると その値は失われる。•  Map.fromListWith を使うと、 キーの重複を許すが、重複した時にどうするかを 確認する。 –  work07.hs
    • モジュールを作る•  ファイル名とモジュールの名前は⼀一致させる。•  ファイルの先頭に、下記のように記述 module Geometry ( sphereVolume , sphereArea , cubeVolume 公開するもの , cubeArea , cuboidVolume , cuboidArea ) where -- 実装を書く
    • モジュールを作る•  Data.Map  とかと同じように、階層を切切りたい場 合は –  フォルダを作成する (Geometry/Sphere.hs) –  module の宣⾔言を、階層付きにする (module Geometry.Sphere)