この場合見えないことなので取るに足らないことです。これも対応できるでしょう。yet.2つめの問題は、一般にIOは失敗し、それをすぐに捉えることができないということです。go.モナド的な見地では、失敗はゼロで表現します。ゆえに必要なことは失敗(例外)の固有の概念をモナドに結びつけるだけです。この点では、これまでやってきたこととは異なる方針をとります。インラインでコメントをつけたこのライブラリの最終バージョンを書きます。them.IOActionオブジェクトはいくつかのファクトリとプライベートな実装(それらは無名クラスかもしれませんが、名前で説明する方が簡単です)を保持する便利なモジュールとして残っています。SimpleActionも同様であり、IOActionのapplyメソッドはそれらのファクトリです。matter.UnitActionはunitアクションのためのクラスです。unitアクションは指定された値を返すが世界の状態は変更しないアクションです。unitはそれのためのファクトリメソッドです。SimpleActionと区別させることはやや奇妙ですが、その上に我々は今優れたモナドにおけるモナドを重要足らしめているところのものの性質がわかるかもしれません。exception.FailureActionはゼロのためのクラスです。それは常に例外をスローするIOActionです。UserExceptionはそういう例外の1つです。failとioErrorメソッドはゼロを生成するファクトリメソッドですioErrorが任意の例外を引数に取りその例外をスローするアクションを返すのに対して、failは文字列を引数に取りUserExceptionを発生させるアクションを返します。IOActionのflatMapとChainedActionは変わっていません。mapは実はunitメソッドを呼び出すように変わりました。モナド則を満たすためです。便利なものを2つばかり追加しました。どちらの結果を戻すのかという疑問があります。getString」はプロンプトを表示しユーザーのレスポンスを戻すアクションを生成します。message.今ゼロを得たので、モナド則に従うだけでフィルターメソッドを追加することができます。ここで2つの形式のフィルターメソッドを作成しました。1つはフィルターがマッチしなかった理由を示すためにユーザーが指定したメッセージを引数に取りますが、もう1つはSからが必要とするインターフェースを満たし一般的なエラーメッセージを使います。action.ゼロはまたモナド的な加算を作成することができるということを意味します。それを作成するためのある基盤として、HandlingActionは他のアクションをラップしそのアクションが例外をスローすればその例外をハンドラーに渡すというアクションです。onErrorはHandlingActionを生成するファクトリメソッドです。最後に、「or」はモナド的な加算です。それは基本的にこのアクションがもし例外とともに失敗すれば代わりのアクションを試すということを述べています。sameIOApplicationの最終バージョンも変わりません。action.RTConsoleはほとんど変わっていませんが、printlnの類似のものとしてputLineメソッドを追加しました。getStringをvalへ変えました。?常に同じアクションだからです。action.さあHelloWorldアプリケーションでこの新しい機能性のいくつかを試してみましょう。sayHelloは文字列から空くshんを生成します。文字列が名前として認識できるなら結果は適切な(もしくは不適切な)あいさつになります。なければアクションは失敗します。getString.askは指定した文字列を表示してそれを取得するアクションを生成する便利なメソッドです。>>演算子はアクションの結果がgetStringの結果であることを確かめます。action.processsStringは任意の文字列を引数に取り、もしそれが「quit」ならさようならを言うアクションを生成します。他の文字列ならsayHelloを呼び出します。結果はsayHelloが失敗した場合「or」を使って他のアクションと組み合わせます。loop.ループは興味深いです。することができるという理由だけでvalとして定義しています。defと同様に動作します。ゆえに再帰関数であるという意味においては完全にはループではありませんが、再帰的な値であるので今度はループに基づくものとして定義されているprocessStringの見地から定義されます。specifies.iomain関数はイントロを表示しループアクションが指定することを実行するアクションを生成してすべてを開始します。why.警告:ライブラリを実装した手段により、このループは最終的にスタックを破壊するかもしれません。プロダクションコードでこれを使わないでください。理由はコメントを読んでみてください。}}jyukutyoコメント理由というのはこのコメントだと思う。4要は、loopが末尾再帰ではないからというのが理由らしい。ループは単なるループではなくて、結局はChainedActionのインスタンスである。ChainedActionのapplyメソッドは末尾再帰にできない。自身のapplyメソッドではなく任意のIOActionのapplyメソッド呼び出しでなければならない、と。末尾再帰でない以上、その関数呼び出しから戻ってきた後の処理の情報をスタックに保存するので、再帰が深くなればスタックの使用量が増え、いつかはあふれるということ。sense.この記事ではインスタンスが実行を待つアクションであることをはっきりさせるためにIOモナドを「IOAction」と呼びました。ScalaにおけるIOモナドの実践的な価値を少しわかっていただけたでしょう。私はここで参照透過性について説こうとしているわけではありません。IOモナドはいかなる意味においても明らかにコレクションでないモナドのもっとも単純な1つです。expressions.まだIOモナドのインスタンスをコンテナとして見るかもしれません。値を格納する代わりにIOモナドは式を格納します。flatMapとmapは本質的に埋め込まれた式をより複雑な式へ変換します。computation.おそらくより役に立つ観念的なモデルはIOモナドのインスタンスを計算や関数としてみることです。flatMapはより複雑な計算を生成するために計算に関数を適用するものとして見ることができます。complicated.この連載の最後のパートではコンテナと計算モデルを統合する手段をカバーします。最初により少し複雑な何かをするためにモナドの象の群れを使ったアプリケーションを見せることによってモナドがどれだけ役に立つのかを述べたいです。「モナドは象だ」の翻訳まとめScalaでCPS(継続渡しスタイル)»プロフィールid:jyukutyo元アルバイト塾講師なソフトウェアエンジニアです。京都にあるモバイル系企業で働いています。Blog|ブログを報告する。