F#のコンピュテーション式

1,737 views

Published on

Published in: Software
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,737
On SlideShare
0
From Embeds
0
Number of Embeds
132
Actions
Shares
0
Downloads
10
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

F#のコンピュテーション式

  1. 1. F#のコンピュテーション式 2014/03/29 #kyon_kao_wedding @pocketberserker
  2. 2. まずはじめに  きょんさん、かおりさん、おめでとうございます!  Twitterで知り合って2か月後にSCMBC、TDDBCを開催し たあのころが懐かしい…
  3. 3. お前誰よ  中山 / なかやん / ペンギン / 残KEN / もみあげ  どこにでもいるふつーの社会人  Microsoft MVP For F# (2013/04/01 ~ 2014/03/31)  2013/04~ ゲーム開発(新卒) -> 2013/11~ (SI)  ぶれきょん共同図書室分室管理人  他言語のライブラリを移植する日々  Scala(z) / Haskell / C++ / Erlang とかにも興味あり
  4. 4. 本日のお題  コンピュテーション式とは  コンピュテーション式の実装方針
  5. 5. 話さないこと  コンピュテーション式の変換規則  カスタムオペレーターの詳細  モナドとは
  6. 6. 注意  個人的意見強め  他のF#erは異なる意見である可能性があります
  7. 7. 結論を一言で
  8. 8. 結論を一言で  コンピュテーション式はモナド用の構文を意識している部 分がある
  9. 9. F#とは  マルチパラダイム  CLI準拠の実行環境上で動作  オープンソース(Apache 2.0)  コミュニティはだいたいゆるふわ
  10. 10. コンピュテーション式  順番に配列したり結合できる計算を記述するのに便利な構 文を提供するもの  変換規則に従って式変形を行う
  11. 11. 標準提供されているもの  seq  シーケンス  seq<‘a>  async  非同期計算  Async<‘a>  query  データセット  seq<‘a>, IEnumerable<‘a>, IQueryable<‘a>
  12. 12. 定義したら使える構文一覧  { let hoge = … in … }  { let! hoge = … in … }  { return hoge }  { return! hoge }  { yield hoge }  { yield! hoge }  { use hoge = … in … }
  13. 13. 定義したら使える構文一覧  { use! hoge = … in … }  { If pred then … else … }  { If pred then … }  { while pred do … }  { for … in … do … }  { try … with … }  { try … finally … }  その他いくつか
  14. 14. 変換後に出現するメソッド Return, ReturnFrom, Bind, Yield, YieldFrom, Using, Zero, Combine, For, While, TryWith, TryFinally, Source, Run, Delay, Quote, Join, GroupJoin
  15. 15. 用語的な話
  16. 16. なんでコンピュテーション式?  初期は「計算式」と呼ばれていたらしい…?  私がF#を学び始めた頃まで  日本コニュニティが改善案を検討して要望したとか  経緯は他のF#erにお尋ねください
  17. 17. キーワード名  基本はモナドを意識したキーワード or F#のキーワード  名前の意図は実装依存  仕様には変換規則しか書かれていない  計算文脈を慎重に考える必要がある  モナド的な解釈?C#のキーワード的な解釈?独自?  モナド用と思われていることが多いため、明記してお かないと「モナド則満たしてない!」とか飛んできか ねない
  18. 18. 実装とか
  19. 19. 組込コンピュテーション式が少ない  構文に関する考えは人それぞれ  同じ型用のコンピュテーション式でも実装は様々考えられ る  Option(Maybe)型だけで少なくとも4つの異なる実装 がNuGet上のライブラリに存在する  Basis.Coreのものが実用的  構文を絞っても問題なさそうなもののみ実装した…?
  20. 20. どの構文でコンパイルエラーなのか  コンピュテーション式は変換規則にしたがって展開される  紙とペンで1つずつ式変換を記述してください  そのうち型のあわない部分が見つかります  ペア作業おすすめ
  21. 21. 高階ことりちゃんと休憩タイム コンピュテーション式を 定義したくなったかな?
  22. 22. コンピュテーション式実装 1. 必要な構文を洗い出す 2. Builderクラスを用意する 3. 変換規則に現れるメソッドを定義する 4. オブジェクトを生成する
  23. 23. コンピュテーション式の実装方針
  24. 24. コンピュテーション式の実装方針  do記法, for式のエミュレーション  データセットの計算を解りやすく  計算を制御する
  25. 25. 1. do構文, for式のエミュレーション
  26. 26. 1. do構文, for式のエミュレーション  一番よく使われるパターン  HaskellのdoもしくはScalaのforのような動作  モナド則(単位元律、結合律)を満たす範囲で実装
  27. 27. 必要なもの  Return(or Yield), Bindメソッド  計算が単位元律、結合律を満たすこと  Zeroメソッドも定義しておいたほうが無難  ZeroがないとIf then が使えない  Haskellのguard関数、Scalaのfor式内でのifの代替  利便性を考えてReturnFromを実装するが多い
  28. 28. 例: Option(Maybe、Optional)型用に 定義 type OptionBuilder() = member this.Return(x) = Some x member this.ReturnFrom(x: _ option) = x // Someならfを適用してSomeに包む、Noneならそのまま member this.Bind(x, f) = Option.bind f x member this.Zero() = None let option = OptionBuilder()
  29. 29. 使ってみる let div x y = option { let! x = x let! y = y if y <= 0 then return x / y } div (Some 4) (Some 2) // = (Some 2) div (Some 1) (Some 0) // = None
  30. 30. 採用基準  シンプルな実装にしたい  多言語から移植したい
  31. 31. 2. データセットの計算をわかりやすく
  32. 32. 2. データセットの計算をわかりやすく  データ操作用途に使うことが多い(?)  データセットを操作しやすい形に実装  処理を連想しやすい独自構文を追加していく
  33. 33. 必要なもの  Yield, YieldFrom, For  必要なカスタムオペレーターを定義
  34. 34. 補足  カスタムオペレーターを定義した場合、制御構文が使えな くなる  If, match, try with, try finally  F# 3.1時点での仕様
  35. 35. 採用基準  計算それぞれに名前をつけたい
  36. 36. 3. 計算を制御する
  37. 37. 3. 計算を制御する  呼び出すキーワードによって細かい制御を行う  エミュレーションではない独自構文として使う
  38. 38. 必要なもの  カスタムオペレータ、Quote以外  場合によってはStateか継続の知識が必要
  39. 39. 例: Basis.Core.OptionBuilder  https://github.com/BasisLib/Basis.Core/blob/v1.1.3/Bas is.Core/Option.fs#L23  制御構文内でreturn, return!を使用するとそれ以降の計算 を行わない  while内でreturnを扱える  returnとyieldをC#的な意図で使える
  40. 40. 例: Basis.Core.OptionBuilder let x = 2 option { if true then return x return! None } //よくあるOptionBuilderだと None // Basis.Coreだと Some 2
  41. 41. 補足  カスタムオペレーターは使用できない  Stateを用いた実装はパフォーマンスが若干落ちる  内部でのパターンマッチ回数が多くなりやすい  継続を用いた実装はラップしにくい  慣れたらそうでもないという噂はある  機能が豊富な分重量級
  42. 42. キーワードごとに計算を制御する理由  式変換で実装される以上、どう足掻いてもメソッドは実行される  option { if true then return x; return y } で (Some y) になってし まう  do構文やfor式では発生しない問題(だと思う)  Returnを呼び出したかどうかの状態を持っておく必要がある  でもBuilder内に状態を持ちたくない  シンタックスハイライトが消えたりする  ので、Stateか継続を使う
  43. 43. Basis.Coreの今後
  44. 44. 同じ型についてコンピュテーション式を 複数提供  v1.1.3はStateを用いたコンピュテーション式のみ提供だった  v2.0では軽量版、State版、Cont版を提供予定  軽量版はreturn, bind程度をサポート予定  用途によって使い分ける  モジュールを分けて提供(ComputationExpr.State.Optionとか?)
  45. 45. まとめ  コンピュテーション式はモナド用の構文を意識している部 分がある  すごいゆるふわF#学ぼう!
  46. 46. おまけ
  47. 47. コンピュテーション式の拡張方法1  コンピュテーション式を構成するBuilderは(OOP的な意 味での)クラス  クラスなので拡張メソッド、オーバーロードを適用できる  ので、既存のコンピュテーション式に介入できないことも ない  実際にやっているところを見たことはない
  48. 48. コンピュテーション式の拡張方法2  Builderのメソッドはpublic  つまりラップして新たなBuilderを定義すれば良い
  49. 49. 参考資料  詳説コンピュテーション式  http://bleis-tift.hatenablog.com/entry/computation- expression  変換規則に関する一番詳しい日本語解説記事  The F# 3.0 Language Specification  http://research.microsoft.com/en- us/um/cambridge/projects/fsharp/manual/spec.html#_Toc3 35818835  上記URLはコンピュテーション式への直リンク
  50. 50. 参考資料  圏論の基礎 – 丸善出版 2012/07  モナド則の名前とか  HaskellのdoとScalaのfor式とEitherとMonadPlus – Scala とか・・・  http://d.hatena.ne.jp/xuwei/20130517/1368814058  HaskellのguardとScalaのfor式を調べていたらヒット した
  51. 51. 参考資料  高階ことりちゃん  http://tkotori.github.io/  画像のライセンスはCC-BY-SA 3.0

×