Tryを単なるエラー情報の入れ物と見てしまうと、普通のオブジェクト指向プログラミングの範囲の利用になり、関数型プログラミングとしては冗長なコーディングをすることになってしまいます。
Tryの価値はモナドである点にあるので、モナド的な使用方法を採るのがTryを活かす道です。
基本フォーム
Tryを使った基本フォームを考えてみました。
def f(a: Int, b: Int) { Try { // Try処理の本体 a / b } map { // 例外が発生しない処理 x => x + 1 } flatMap { // 例外が発生する処理 x => Try { x / (b - 1) } } match { // 終了処理 case Success(v) => println(v) case Failure(e) => println(e) } }
プログラム内にもコメントしましたが以下の4種類の部品から構成されます。
- Try処理の本体
- 例外が発生しない処理
- 例外が発生する処理
- 終了処理
処理を複数の関数を合成して記述するのが関数型のアプローチです。例外が発生しないものはmapメソッド、例外が発生する可能性のあるものはTryでくるんでflatMapメソッドで合成していきます。
Try処理の本体から終了処理にかけてパイプライン的な流れで考えるとよいでしょう。
Try処理の本体
Try処理の本体は、例外が発生する可能性がある処理をTryで包んで実行する処理になります。この結果Tryモナドが生成されるので、これに対してモナディック、パイプライン的に関数を適用していきます。
例外が発生しない処理
例外が発生しない処理はmapメソッドを使って関数を適用します。
例外が発生する処理
例外が発生する可能性のある処理は、関数をTryで包んで実行したものをflatMapメソッドを使って適用します。この結果Tryモナドが入れ子になりますが、flatMapの効果で自動的に一つにまとめられます。
終了処理
Tryを使った処理は以下の4種類の終了方法があります。
- Tryのまま返す
- 値を返す
- 副作用のある処理を行なって完了
- 値を返すか例外を投げる
今回はこの中の「副作用のある処理を行なって完了」にしてみました。
諸元
- Scala 2.10.0-M7
0 件のコメント:
コメントを投稿