More Related Content Similar to FP習熟度レベルとFSharpxのIteratee (20) FP習熟度レベルとFSharpxのIteratee2. 自己紹介
• 中山 / なかやん
• @pocketberserker / id:pocketberserker
• どこにでもいるふつーのサーガ大学院生
• F# / Haskell / (Erlang) / TDD / テスト
• FSharpx の Contributor らしい…
6. 私と関数型
関数型 = Lisp でしょ?
Lisp こわいから関数型こわい
29. 力の階層と節度
関数プログラミングの道しるべ
“函数プログラミングの集い 2011” での山本さんの
発表資料
33. 高階関数になれるためにも・
・・
• 訓練あるのみ
• 一度再帰で書いて、後でリファクタリングで
きないか検討
• そのうち一気に高階関数のほうで書けるよう
になる
34. 高階関数になれるためにも・
・・
• 訓練あるのみ
• 一度再帰で書いて、後でリファクタリングで
きないか検討
• そのうち一気に高階関数のほうで書けるよう
になる
• 注意:リファクタリングにはテストコード
必須
59. 入力データを表す Stream
type Stream’a =
| Chunk of ’a
| Empty
| EOF
データ Chunk, 空 Empty, 終端 EOF
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. 生産者 Enumerator
type Enumerator’el,’a =
Iteratee’el,’a -
Iteratee’el,’a
Iteratee にデータを与える
62. パイプ Enumeratee
type Enumeratee’elo,’eli,’a =
Iteratee’eli,’a -
Iteratee’elo, Iteratee’eli,’a
enumerator からデータを受け取り Iteratee に渡す
63. 疲れたのでちょっと休憩
ことりちゃんマジかわいい本
画像は mzp さん、bleis さんの許可を得て掲載しています
73. FSharpx の Iteratee
• F#での Iteratee 実装
• (∗ ) や ( ∗) も実装されている
• Iteratee.List と Iteratee.Binary(ByteString)
74. FSharpx の Iteratee
• F#での Iteratee 実装
• (∗ ) や ( ∗) も実装されている
• Iteratee.List と Iteratee.Binary(ByteString)
• 欠点 1:Enumeratee が 1 つも実装されてい
ない
75. FSharpx の Iteratee
• F#での Iteratee 実装
• (∗ ) や ( ∗) も実装されている
• Iteratee.List と Iteratee.Binary(ByteString)
• 欠点 1:Enumeratee が 1 つも実装されてい
ない
• 欠点 2:Eumeratee と Iteratee を合成する関
数がない
76. FSharpx の Iteratee
• F#での Iteratee 実装
• (∗ ) や ( ∗) も実装されている
• Iteratee.List と Iteratee.Binary(ByteString)
• 欠点 1:Enumeratee が 1 つも実装されてい
ない
• 欠点 2:Eumeratee と Iteratee を合成する関
数がない
77. FSharpx の Iteratee
• F#での Iteratee 実装
• (∗ ) や ( ∗) も実装されている
• Iteratee.List と Iteratee.Binary(ByteString)
• 欠点 1:Enumeratee が 1 つも実装されてい
ない
• 欠点 2:Eumeratee と Iteratee を合成する関
数がない
だったのが一昨日までの話
82. 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
85. 実行その 2
run | listFeeder consumer
XXX 1
XXX 2
XXX 3
XXX 4
86. 入力を増やす
let fileFeeder =
IO.readFile @.FILE
| Seq.map ByteString.ofString
| Seq.toList
| enumList
87. 実行その 3
run | (fileFeeder listFeeder) consumer
XXX 1
XXX 2
XXX 3
XXX 4
XXX 5
XXX 6
XXX 7
XXX 8
88. お仕事を増やす
let consumer2 =
iteratee {
let! mw = head
match mw with
| None - ()
| Some w -
printf YYY
w
| (ByteString.singleton ByteString.toString)
| printfn %s
}
89. 実行その 4
run | (fileFeeder listFeeder) (consumer2 . consumer)
YYY 1
XXX 2
XXX 3
XXX 4
XXX 5
XXX 6
XXX 7
XXX 8
90. 仲介者を使った実行
run | listFeeder (joinI (isolate 2 consumer))
XXX 1
XXX 2
isolate は与えられた数の個数だけ入力を取り出す
98. 余談:Iteratee 触るまでにかかった期間とか
• すごい H 本再読 1 週間
• Haskell の enumerator コードリーディング 3
日?
• scalaz コードリーディング挫折 2 日
• FSharpx.Iteratee のバグ潰し 1 日
99. 余談:Iteratee 触るまでにかかった期間とか
• すごい H 本再読 1 週間
• Haskell の enumerator コードリーディング 3
日?
• scalaz コードリーディング挫折 2 日
• FSharpx.Iteratee のバグ潰し 1 日
• FSharpx.Iteratee 追加実装 1 週間