Streaming data processing ライブラリの紹介 (主に Conduit)

956 views

Published on

「名前は聞いたことがあるけど,どういうものなの?」という方向けの資料です.

Published in: Technology
  • Be the first to comment

Streaming data processing ライブラリの紹介 (主に Conduit)

  1. 1. Streaming data processing ライブラリの紹介 (主に conduit) KrdLab (2013/12/21)
  2. 2. はじめに  ときどきコードが出てきますが  「ふーん,こんな感じなのか」  って見てもらえれば幸いです
  3. 3. 今回の内容  これは何?  何があるの?  Conduit の紹介  ほんの少しだけ中身をのぞくと…  まとめ
  4. 4. Streaming data processing ライブラリって何?  ストリームデータに対して統一インタフェースを提供  どこから来たデータであっても同じように扱える  リソースの解放をコントロール  lazy IO の問題を解決
  5. 5. 統一されたインタフェース  ソケット/ファイル/メモリ,どこから来たデータなのかに関係なく扱える  データの生成/変換/消費  これらを記述する primitive  これらを連結する operator  ライブラリごとに若干名前が異なりますが…     Source/Process Source/Conduit/Sink Pipe/Proxy InputStream/OutputStream -- だいたいこんな感じ run $ source (ope) process (ope) ... ストリームデータ の抽象化
  6. 6. リソースの解放をコントロール (1/2)  lazy IO のみで構成すると大きなデータでもコンスタントなメモリで処理できる  しかし,lazy IO はリソース解放のタイミングが難しい  GC 任せにすると解放タイミングが非決定的  かといって完璧に管理するのも大変 -- 単純かつ極端な例 (もちろんコンパイルは通る) main = do s <- withFile “test.txt” ReadMode hGetContents putStr s -- あっ… 表示されない…  例えば hGetContents の返す String はすべてのデータを表す  えっ!?  引き回しはじめたらどこで閉じたら良いのかわからない… (参考) http://www.haskell.org/haskellwiki/Iteratee_I/O
  7. 7. リソースの解放をコントロール (2/2)  リソースは使い終わったら即時回収  リソースは貴重品  もちろん “constant memory” main = runResource $ sourceFile “test.txt” $$ sinkHandle stdout  “deterministic resource handling”  “resource and exception safety”
  8. 8. 有名どころの Implementasions  conduit  Yesod の作者が作っている  ResourceT でリソース管理  pipes  よく conduit と一緒に取り上げられ,確か conduit の実装に影響を与えていたはず  リソースのあたりは pipes-safe  io-streams  他と少し毛色が違う,IO をベースとした API  リソースのあたりは catch/bracket/with*  あと machines というものもあるよ!
  9. 9. 今回のターゲット  conduit について紹介します  machines についてはブログ参照  「Haskell の machines に入門してみた,というお話」  http://krdlab.hatenablog.com/entry/2013/03/16/204039
  10. 10. Conduit: リスト操作 -- List の例 import Data.Conduit import qualified Data.Conduit.List as CL main = do l <- CL.sourceList [1..10] $$ CL.map (+1) =$ CL.consume print l -- [2,3,4,5,6,7,8,9,10,11]
  11. 11. Conduit: ファイル操作  宣言的 main = runResourceT $ sourceFile “test.txt” $$ sinkFile “output.txt”  加工したい場合も宣言的にかける main = runResourceT $ sourceFile “test.txt” $= decode utf8 $= CL.map toUpper $= encode utf8 $$ sinkFile “output.txt”
  12. 12. Conduit: Core & Generalized Types  type Source m o  データの生産  type Conduit i m o  データの変換  type Sink i  データの消費  一般化したやつ  type Producer m o  type Consumer i m r  (補足:上 3 つと違って input/output が forall)
  13. 13. Conduit: Operators  各コンポーネントをつなぐ  ($$) :: Source m a -> Sink a m b -> m b  connect  ($=) :: Source m a -> Conduit a m b -> Source m b  fuse  (=$) :: Conduit a m b -> Sink b m c -> Sink a m c  fuse  (=$=) :: Conduit a m b -> ConduitM b c m r -> ConduitM a c m r  fuse
  14. 14. Conduit: Primitives  自分で中身を書きたいときに使う  await :: Monad m => Consumer i m (Maybe i)  上流からの入力を待つ  yield :: Monad m => o -> ConduitM i o m ()  値を下流へ流す  leftover :: i -> ConduitM i o m ()  入力の読み残しを次に渡す
  15. 15. Conduit: Primitives の利用例  リストを加工する例
  16. 16. Conduit: Internal (少しだけです)
  17. 17. Conduit: Internal  data Pipe l i o u m r       l: left over (otherwise Void) i: input values o: output values u: upstream からの戻り値 m: ベースモナド (ex. IO) r: 最終的な戻り値  コンストラクタは 5 種類  HaveOutput/NeedInput/Done/PipeM/Leftover
  18. 18. Conduit: Internal - Core datatype  data ConduitM i o m r     i: input values o: output values m: ベースモナド (最終的に返されるコンテキスト) r: 最終的な戻り値  内部には Pipe を持っている  newtype ConduitM i o m r = ConduitM { unConduitM :: Pipe i i o () m r }
  19. 19. Conduit: Internal - Types  type Source m o = ConduitM () o m ()  type Conduit i m o = ConduitM i o m ()  type Sink i = ConduitM i Void  type Producer m o = forall i. ConduitM i o m ()  type Consumer i m r = forall o. ConduitM i o m r  すべてが Pipe
  20. 20. Conduit: 要するに  ストリームデータを Pipe 構造に変換  処理を Pipe で記述  演算子で連結 ↓  Conduit の処理は Pipe を interpret する
  21. 21. まとめ  良い感じにストリームデータを扱える  統一されたインタフェース  リソース解放のコントロール  いろいろ実装あるけど,今回は conduit を紹介した  良い感じでコンポーネントを書くための primitive も提供されている  内部は Pipe を処理している  すぐに試してみたい人は “FP Haskell Center” を使うと楽です  https://www.fpcomplete.com/

×