F#を学んで感じた関数プログラミング  習熟度レベル+FSharpx の Iteratee        pocketberserker        2012 年 9 月 1 日
自己紹介• 中山 / なかやん• @pocketberserker / id:pocketberserker• どこにでもいるふつーのサーガ大学院生• F# / Haskell / (Erlang) / TDD / テスト• FSharpx の...
私と関数型
私と関数型初期の思い込み
私と関数型関数型 = Lisp でしょ?
私と関数型    関数型 = Lisp でしょ?Lisp こわいから関数型こわい
結論から言えば
結論から言えば• ただの食わず嫌いでした、ごめんなさい
結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で 思い違いを知る
結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で  思い違いを知る• 気がついたら Java から F#に鞍替えしていた
結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で  思い違いを知る• 気がついたら Java から F#に鞍替えしていた• これがちょうど 2 年前の話
学んだり会話したりして感じたこと
学んだり会話したりして感じたこと関数プログラミングにも習熟度レベルがある?
ざっくりと考えてみる
免責事項• 人によって “関数プログラミング (FP)” の定義  は異なる• ここでは:基本副作用を許さず関数が第一級  の値なら FP• 動的型付け:わからないので今回は除外
想像してみた習熟度レベル(言語共通)1. はろー再帰呼び出し2. 再帰より高階関数
想像してみた習熟度レベル(静的型付け編) 1. Option, Either 2. モナドを使う 3. モナド自作
はろー再帰呼び出し
はろー再帰呼び出し• 基本的な部品の一つ
はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい
はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい• でも再帰は最後の手段
はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい• でも再帰は最後の手段• 不必要に多用しているうちは訓練不足
再帰より高階関数
再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける
再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける
再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と いう力関係
再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と  いう力関係• 力の弱いほうを使ったほうがコードがわかり  やすい
再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と  いう力関係• 力の弱いほうを使ったほうがコードがわかり  やすい• 力の弱いものを...
力の階層と節度     関数プログラミングの道しるべ“函数プログラミングの集い 2011” での山本さんの          発表資料
高階関数になれるためにも・            ・・
高階関数になれるためにも・              ・・• 訓練あるのみ
高階関数になれるためにも・              ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで きないか検討
高階関数になれるためにも・              ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで  きないか検討• そのうち一気に高階関数のほうで書けるよう  になる
高階関数になれるためにも・              ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで  きないか検討• そのうち一気に高階関数のほうで書けるよう  になる• 注意:リファクタリングにはテストコード  必須
ここから静的型付けの話
Option(Maybe), Either
Option(Maybe), Either• 値が返ってこないかもしれない計算
Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算
Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算• “カターンゼン!”
Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算• “カターンゼン!”• モナドへの第一歩
モナドを使う
モナドを使う• 使えなくても FP できる(純粋なものは別)
モナドを使う• 使えなくても FP できる(純粋なものは別)• でも使えたら便利!
モナドを使う• 使えなくても FP できる(純粋なものは別)• でも使えたら便利!• 使うところからはじめましょう
モナド自作
モナド自作• まだ見ぬ高み
モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい
モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい• 発表聞いた人は感想教えてください!
モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい• 発表聞いた人は感想教えてください!• と思ったけどハッシュタグ見てたら厳しい かも…
ここまでのまとめ• FP には習熟度レベルがあるぽい• 次に挑戦すべき段差が何か知ることができれ  ば学びやすいのかも• 一歩一歩進めばそのうち上達する• こわくない
FSharpx の Iteratee
Iteratee
Iteratee• I/O の表現の一つ
Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す
Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す• データと処理の分離
Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す• データと処理の分離• コンビネータ的な操作
ソースコードで説明してみる
注意ここからの公用語は(もしかしたら)       F#です
入力データを表す Stream      type Stream’a = | Chunk of ’a | Empty | EOF                            データ Chunk, 空 Empty, 終端 EOF
消費者 Iteratee              type Iteratee’el,’a = | Done of ’a * Stream’el | Error of exn | Continue of   (Stream’el - Itera...
生産者 Enumerator    type Enumerator’el,’a =   Iteratee’el,’a -     Iteratee’el,’a                            Iteratee にデータを与える
パイプ Enumeratee                type Enumeratee’elo,’eli,’a =   Iteratee’eli,’a -     Iteratee’elo, Iteratee’eli,’a         ...
疲れたのでちょっと休憩            ことりちゃんマジかわいい本画像は mzp さん、bleis さんの許可を得て掲載しています
ここからはFSharpx での実装を使って使用方法の紹介
FSharpxって?
FSharpxって?• Core にはない便利な関数の提供
FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders
FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders• ちなみに F#er 内で賛否両論ある模様
FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders• ちなみに F#er 内で賛否両論ある模様• 例:Core だけで既に重量級ライブラリ
FSharpx の Iteratee
FSharpx の Iteratee• F#での Iteratee 実装
FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている
FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)
FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が...
FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が...
FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が...
FSharpx の Iteratee • F#での Iteratee 実装 • (∗ ) や ( ∗) も実装されている • Iteratee.List と Iteratee.Binary(ByteString) • 欠点 1:Enumerat...
おかげで資料を一部作り直すことに…
気持ちを切り替え使ってみよう Enumerator - あどけない話のネタを参考に F#でデモ(時間があれば)
Iteratee を作る                      let rec consumer =  iteratee {    let! mw = head    match mw with    | None - ()    | So...
実行その 1    run | consumer
Enumerator を作ってみる   let listFeeder =  [BS 12B; BS 34B]  | enumList
実行その 2            run | listFeeder consumerXXX 1XXX 2XXX 3XXX 4
入力を増やす                let fileFeeder =  IO.readFile @.FILE  | Seq.map ByteString.ofString  | Seq.toList  | enumList       ...
実行その 3                      run | (fileFeeder  listFeeder) consumer XXX 1 XXX 2 XXX 3 XXX 4 XXX 5 XXX 6 XXX 7 XXX 8       ...
お仕事を増やす                            let consumer2 =  iteratee {    let! mw = head    match mw with    | None - ()    | Some...
実行その 4                                run | (fileFeeder  listFeeder) (consumer2 . consumer)YYY 1XXX 2XXX 3XXX 4XXX 5XXX 6X...
仲介者を使った実行                        run | listFeeder (joinI (isolate 2 consumer))XXX 1XXX 2                                  ...
Iteratee 一覧• fold• length• peek• head• drop• take• 他にもいくつか
Enumerator 一覧• enumerate• enumeratePure1Chunk• enumeratePureNChunk• connect• repeat• replicate• enumList
Enumeratee 一覧• isolate, isolateWhile, isolateUntil• concatMap• map• filter
余談:Iteratee 触るまでにかかった期間とか
余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間
余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3  日?
余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3   日? • scalaz コードリーディング挫折 2 日
余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3   日? • scalaz コードリーディング挫折 2 日 • FSharpx.Iter...
余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3   日? • scalaz コードリーディング挫折 2 日 • FSharpx.Iter...
まとめとか• Iteratee とは• FSharpx 内での実装• Haskell や Scala では使われているらしい• FSharpx は F#の勉強になるよ!
ご清聴ありがとう ございました
FP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIteratee
Upcoming SlideShare
Loading in …5
×

FP習熟度レベルとFSharpxのIteratee

2,403 views

Published on

FP習熟度レベルとFSharpxのIteratee

  1. 1. F#を学んで感じた関数プログラミング 習熟度レベル+FSharpx の Iteratee pocketberserker 2012 年 9 月 1 日
  2. 2. 自己紹介• 中山 / なかやん• @pocketberserker / id:pocketberserker• どこにでもいるふつーのサーガ大学院生• F# / Haskell / (Erlang) / TDD / テスト• FSharpx の Contributor らしい…
  3. 3. 私と関数型
  4. 4. 私と関数型初期の思い込み
  5. 5. 私と関数型関数型 = Lisp でしょ?
  6. 6. 私と関数型 関数型 = Lisp でしょ?Lisp こわいから関数型こわい
  7. 7. 結論から言えば
  8. 8. 結論から言えば• ただの食わず嫌いでした、ごめんなさい
  9. 9. 結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で 思い違いを知る
  10. 10. 結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で 思い違いを知る• 気がついたら Java から F#に鞍替えしていた
  11. 11. 結論から言えば• ただの食わず嫌いでした、ごめんなさい• 初めて参加した勉強会(TDDBC 名古屋)で 思い違いを知る• 気がついたら Java から F#に鞍替えしていた• これがちょうど 2 年前の話
  12. 12. 学んだり会話したりして感じたこと
  13. 13. 学んだり会話したりして感じたこと関数プログラミングにも習熟度レベルがある?
  14. 14. ざっくりと考えてみる
  15. 15. 免責事項• 人によって “関数プログラミング (FP)” の定義 は異なる• ここでは:基本副作用を許さず関数が第一級 の値なら FP• 動的型付け:わからないので今回は除外
  16. 16. 想像してみた習熟度レベル(言語共通)1. はろー再帰呼び出し2. 再帰より高階関数
  17. 17. 想像してみた習熟度レベル(静的型付け編) 1. Option, Either 2. モナドを使う 3. モナド自作
  18. 18. はろー再帰呼び出し
  19. 19. はろー再帰呼び出し• 基本的な部品の一つ
  20. 20. はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい
  21. 21. はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい• でも再帰は最後の手段
  22. 22. はろー再帰呼び出し• 基本的な部品の一つ• これを理解できないと(たぶん)後々つらい• でも再帰は最後の手段• 不必要に多用しているうちは訓練不足
  23. 23. 再帰より高階関数
  24. 24. 再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける
  25. 25. 再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける
  26. 26. 再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と いう力関係
  27. 27. 再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と いう力関係• 力の弱いほうを使ったほうがコードがわかり やすい
  28. 28. 再帰より高階関数• 目的に特化した高階関数は fold 系でも書ける• fold 系は再帰でも書ける• 再帰 > fold 系 > 目的に特化した高階関数 と いう力関係• 力の弱いほうを使ったほうがコードがわかり やすい• 力の弱いものを優先して使っていく
  29. 29. 力の階層と節度 関数プログラミングの道しるべ“函数プログラミングの集い 2011” での山本さんの 発表資料
  30. 30. 高階関数になれるためにも・ ・・
  31. 31. 高階関数になれるためにも・ ・・• 訓練あるのみ
  32. 32. 高階関数になれるためにも・ ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで きないか検討
  33. 33. 高階関数になれるためにも・ ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで きないか検討• そのうち一気に高階関数のほうで書けるよう になる
  34. 34. 高階関数になれるためにも・ ・・• 訓練あるのみ• 一度再帰で書いて、後でリファクタリングで きないか検討• そのうち一気に高階関数のほうで書けるよう になる• 注意:リファクタリングにはテストコード 必須
  35. 35. ここから静的型付けの話
  36. 36. Option(Maybe), Either
  37. 37. Option(Maybe), Either• 値が返ってこないかもしれない計算
  38. 38. Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算
  39. 39. Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算• “カターンゼン!”
  40. 40. Option(Maybe), Either• 値が返ってこないかもしれない計算• 失敗や例外を投げる計算• “カターンゼン!”• モナドへの第一歩
  41. 41. モナドを使う
  42. 42. モナドを使う• 使えなくても FP できる(純粋なものは別)
  43. 43. モナドを使う• 使えなくても FP できる(純粋なものは別)• でも使えたら便利!
  44. 44. モナドを使う• 使えなくても FP できる(純粋なものは別)• でも使えたら便利!• 使うところからはじめましょう
  45. 45. モナド自作
  46. 46. モナド自作• まだ見ぬ高み
  47. 47. モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい
  48. 48. モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい• 発表聞いた人は感想教えてください!
  49. 49. モナド自作• まだ見ぬ高み• 先ほど dico leque さんが発表していたらしい• 発表聞いた人は感想教えてください!• と思ったけどハッシュタグ見てたら厳しい かも…
  50. 50. ここまでのまとめ• FP には習熟度レベルがあるぽい• 次に挑戦すべき段差が何か知ることができれ ば学びやすいのかも• 一歩一歩進めばそのうち上達する• こわくない
  51. 51. FSharpx の Iteratee
  52. 52. Iteratee
  53. 53. Iteratee• I/O の表現の一つ
  54. 54. Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す
  55. 55. Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す• データと処理の分離
  56. 56. Iteratee• I/O の表現の一つ• データを読み込んでコールバック関数に渡す• データと処理の分離• コンビネータ的な操作
  57. 57. ソースコードで説明してみる
  58. 58. 注意ここからの公用語は(もしかしたら) F#です
  59. 59. 入力データを表す Stream type Stream’a = | Chunk of ’a | Empty | EOF データ Chunk, 空 Empty, 終端 EOF
  60. 60. 消費者 Iteratee type Iteratee’el,’a = | Done of ’a * Stream’el | Error of exn | Continue of (Stream’el - Iteratee’el,’a) 処理終了状態 Done, 計算途中 Continue, エラーError
  61. 61. 生産者 Enumerator type Enumerator’el,’a = Iteratee’el,’a - Iteratee’el,’a Iteratee にデータを与える
  62. 62. パイプ Enumeratee type Enumeratee’elo,’eli,’a = Iteratee’eli,’a - Iteratee’elo, Iteratee’eli,’a enumerator からデータを受け取り Iteratee に渡す
  63. 63. 疲れたのでちょっと休憩 ことりちゃんマジかわいい本画像は mzp さん、bleis さんの許可を得て掲載しています
  64. 64. ここからはFSharpx での実装を使って使用方法の紹介
  65. 65. FSharpxって?
  66. 66. FSharpxって?• Core にはない便利な関数の提供
  67. 67. FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders
  68. 68. FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders• ちなみに F#er 内で賛否両論ある模様
  69. 69. FSharpxって?• Core にはない便利な関数の提供• Core, Http, Observable, TypeProviders• ちなみに F#er 内で賛否両論ある模様• 例:Core だけで既に重量級ライブラリ
  70. 70. FSharpx の Iteratee
  71. 71. FSharpx の Iteratee• F#での Iteratee 実装
  72. 72. FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている
  73. 73. FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)
  74. 74. FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が 1 つも実装されてい ない
  75. 75. FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が 1 つも実装されてい ない• 欠点 2:Eumeratee と Iteratee を合成する関 数がない
  76. 76. FSharpx の Iteratee• F#での Iteratee 実装• (∗ ) や ( ∗) も実装されている• Iteratee.List と Iteratee.Binary(ByteString)• 欠点 1:Enumeratee が 1 つも実装されてい ない• 欠点 2:Eumeratee と Iteratee を合成する関 数がない
  77. 77. FSharpx の Iteratee • F#での Iteratee 実装 • (∗ ) や ( ∗) も実装されている • Iteratee.List と Iteratee.Binary(ByteString) • 欠点 1:Enumeratee が 1 つも実装されてい ない • 欠点 2:Eumeratee と Iteratee を合成する関 数がないだったのが一昨日までの話
  78. 78. おかげで資料を一部作り直すことに…
  79. 79. 気持ちを切り替え使ってみよう Enumerator - あどけない話のネタを参考に F#でデモ(時間があれば)
  80. 80. Iteratee を作る let rec consumer = iteratee { let! mw = head match mw with | None - () | Some w - printf XXX w | (ByteString.singleton ByteString.toString) | printfn %s return! consumer } head はストリームを消費して要素を取り出すIteratee
  81. 81. 実行その 1 run | consumer
  82. 82. Enumerator を作ってみる let listFeeder = [BS 12B; BS 34B] | enumList
  83. 83. 実行その 2 run | listFeeder consumerXXX 1XXX 2XXX 3XXX 4
  84. 84. 入力を増やす let fileFeeder = IO.readFile @.FILE | Seq.map ByteString.ofString | Seq.toList | enumList
  85. 85. 実行その 3 run | (fileFeeder listFeeder) consumer XXX 1 XXX 2 XXX 3 XXX 4 XXX 5 XXX 6 XXX 7 XXX 8
  86. 86. お仕事を増やす let consumer2 = iteratee { let! mw = head match mw with | None - () | Some w - printf YYY w | (ByteString.singleton ByteString.toString) | printfn %s }
  87. 87. 実行その 4 run | (fileFeeder listFeeder) (consumer2 . consumer)YYY 1XXX 2XXX 3XXX 4XXX 5XXX 6XXX 7XXX 8
  88. 88. 仲介者を使った実行 run | listFeeder (joinI (isolate 2 consumer))XXX 1XXX 2 isolate は与えられた数の個数だけ入力を取り出す
  89. 89. Iteratee 一覧• fold• length• peek• head• drop• take• 他にもいくつか
  90. 90. Enumerator 一覧• enumerate• enumeratePure1Chunk• enumeratePureNChunk• connect• repeat• replicate• enumList
  91. 91. Enumeratee 一覧• isolate, isolateWhile, isolateUntil• concatMap• map• filter
  92. 92. 余談:Iteratee 触るまでにかかった期間とか
  93. 93. 余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間
  94. 94. 余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3 日?
  95. 95. 余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3 日? • scalaz コードリーディング挫折 2 日
  96. 96. 余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3 日? • scalaz コードリーディング挫折 2 日 • FSharpx.Iteratee のバグ潰し 1 日
  97. 97. 余談:Iteratee 触るまでにかかった期間とか • すごい H 本再読 1 週間 • Haskell の enumerator コードリーディング 3 日? • scalaz コードリーディング挫折 2 日 • FSharpx.Iteratee のバグ潰し 1 日 • FSharpx.Iteratee 追加実装 1 週間
  98. 98. まとめとか• Iteratee とは• FSharpx 内での実装• Haskell や Scala では使われているらしい• FSharpx は F#の勉強になるよ!
  99. 99. ご清聴ありがとう ございました

×